Skip to content

Commit 4281fd4

Browse files
committed
Merge branch 'develop' of github.com:magento/magento2-functional-testing-framework into waitforpageload-after-amonpage
2 parents f52a408 + fb1e4b7 commit 4281fd4

File tree

73 files changed

+2603
-450
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+2603
-450
lines changed

CHANGELOG.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,56 @@
11
Magento Functional Testing Framework Changelog
22
================================================
33

4+
2.2.0
5+
-----
6+
### Enhancements
7+
* Traceability
8+
* Javascript errors are now logged and reported in test output.
9+
* Test failures are no longer overwritten by failures in an `<after>` hook.
10+
* Tests will no longer execute an `<after>` hook twice if a failure triggered in the `<after>` hook.
11+
* Tests marked with `<group value="skip">` will now appear in generated Allure reports.
12+
* Along with the above, the `robo group` command no longer omits the `skip` group (skipped tests are picked up but not fully executed).
13+
* Modularity
14+
* MFTF no longer relies on relative pathing to determine its path to tests or Magento (favoring composer information if available).
15+
* Tests and test materials are now read in from Magento modules as well as extensions in addition to `dev/tests/acceptance`.
16+
* See DevDocs `Getting Started` for details on expected paths and merge order.
17+
* Customizability
18+
* Creation of Suites is now supported
19+
* `<suite>` can include tests via `name`, module, or `<group>` tags.
20+
* Consolidation of preconditions can be achieved via use of `<before/after>` tags in a `<suite>`
21+
* All normal test actions are supported
22+
* Data returned from actions is not available for reference in subsequent tests (`createData` or `grab` actions).
23+
* `robo generate:tests` generates all suites and tests, and can be given a JSON configuration to generate specific test/suites.
24+
* See MFTF Devdocs "Suite" page for more details.
25+
* `<deleteData>` may now be called against a `url` instead of a stepKey reference.
26+
* `<dragAndDrop>` may now be given an additional `x/y` offset.
27+
* `<executeJS>` now returns a variable based on what the executed script returns.
28+
* Added `<element>` `type="block"`.
29+
* `<page>` elements may now be blank (contain no child sections).
30+
* Maintainability
31+
* `robo generate:tests --config parallel` now accepts a `--lines` argument, for grouping and sorting based on test length.
32+
* `robo generate:tests` now checks for:
33+
* Duplicate step keys within an `actionGroup`.
34+
* Ambiguous or invalid `stepKey` references (in merge files).
35+
* `robo generate:tests` now suppresses warnings by default. The command now accepts a `--verbose` flag to show full output including warnings.
36+
37+
### Fixes
38+
* Exception message for the `<conditionalClick>` action now correctly references the `selector` given.
39+
* Usage of multiple parameterized elements in a `selector` now correctly resolves all element references.
40+
* Usage of multiple uniqueness references on the same entity now generate correctly.
41+
* Persisted entity references are correctly interpolated with `<page>` url of `type="admin"`.
42+
* Metadata that contains 2 or more params in its `url` now correctly resolve parameters.
43+
* Arguments can now be passed to `x` and `y` attributes in `actionGroup`.
44+
* Arguments can now be passed to nested `<assert*>` action elements.
45+
* The `<seeInField>` action can now be used to assert against empty strings.
46+
* Empty `<data>` elements within an `<entity>` now generate correctly.
47+
* Mapping of the `<magentoCLI>` to the custom command has been fixed.
48+
49+
### GitHub Issues/Pull requests:
50+
* [#89](https://github.com/magento/magento2-functional-testing-framework/pull/89) -- Add ability to use array entities as arguments.
51+
* [#68](https://github.com/magento/magento2-functional-testing-framework/issues/68) -- Excessive double quotes are being generated in WaitForElementChange method arguments (fixed in [#103](https://github.com/magento/magento2-functional-testing-framework/pull/103))
52+
* [#31](https://github.com/magento/magento2-functional-testing-framework/issues/31) -- Can't run tests without a store having "default" store code (fixed in [#86](https://github.com/magento/magento2-functional-testing-framework/pull/86))
53+
454
2.1.2
555
-----
656
### Enhancements

bin/static-checks

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ set -e
88
echo "==============================="
99
echo " CODE SNIFFER"
1010
echo "==============================="
11-
vendor/bin/phpcs ./src --standard=./dev/tests/static/Magento
11+
vendor/bin/phpcs ./src --standard=./dev/tests/static/Magento --ignore=src/Magento/FunctionalTestingFramework/Group,src/Magento/FunctionalTestingFramework/AcceptanceTester.php
1212
vendor/bin/phpcs ./dev/tests/unit --standard=./dev/tests/static/Magento
1313
vendor/bin/phpcs ./dev/tests/verification --standard=./dev/tests/static/Magento --ignore=dev/tests/verification/_generated
1414
echo ""
@@ -22,7 +22,7 @@ echo ""
2222
echo "==============================="
2323
echo " MESS DETECTOR"
2424
echo "==============================="
25-
vendor/bin/phpmd ./src text /dev/tests/static/Magento/CodeMessDetector/ruleset.xml --exclude _generated
25+
vendor/bin/phpmd ./src text /dev/tests/static/Magento/CodeMessDetector/ruleset.xml --exclude _generated,src/Magento/FunctionalTestingFramework/Group,src/Magento/FunctionalTestingFramework/AcceptanceTester.php
2626
echo ""
2727

2828
echo "==============================="

bin/static-checks.bat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55

66
@echo off
77
@echo ===============================PHP CODE SNIFFER REPORT===============================
8-
call vendor\bin\phpcs .\src --standard=.\dev\tests\static\Magento
8+
call vendor\bin\phpcs .\src --standard=.\dev\tests\static\Magento --ignore=src\Magento\FunctionalTestingFramework\Group,src\Magento\FunctionalTestingFramework\AcceptanceTester.php
99
call vendor\bin\phpcs .\dev\tests\unit --standard=.\dev\tests\static\Magento
1010
call vendor\bin\phpcs .\dev\tests\verification --standard=.\dev\tests\static\Magento --ignore=dev\tests\verification\_generated
1111

1212
@echo ===============================COPY PASTE DETECTOR REPORT===============================
1313
call vendor\bin\phpcpd .\src
1414

1515
@echo "===============================PHP MESS DETECTOR REPORT===============================
16-
vendor\bin\phpmd .\src text \dev\tests\static\Magento\CodeMessDetector\ruleset.xml --exclude _generated
16+
vendor\bin\phpmd .\src text \dev\tests\static\Magento\CodeMessDetector\ruleset.xml --exclude _generated,src\Magento\FunctionalTestingFramework\Group,src\Magento\FunctionalTestingFramework\AcceptanceTester.php
1717

1818
@echo ===============================MAGENTO COPYRIGHT REPORT===============================
1919
echo msgbox "INFO:Copyright check currently not run as part of .bat implementation" > "%temp%\popup.vbs"

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "magento/magento2-functional-testing-framework",
33
"description": "Magento2 Functional Testing Framework",
44
"type": "library",
5-
"version": "2.1.2",
5+
"version": "2.2.0",
66
"license": "AGPL-3.0",
77
"keywords": ["magento", "automation", "functional", "testing"],
88
"config": {
@@ -17,7 +17,7 @@
1717
"flow/jsonpath": ">0.2",
1818
"fzaninotto/faker": "^1.6",
1919
"mustache/mustache": "~2.5",
20-
"symfony/process": ">=2.7 <3.4",
20+
"symfony/process": "^2.8 || ^3.1 || ^4.0",
2121
"vlucas/phpdotenv": "^2.4"
2222
},
2323
"require-dev": {

composer.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dev/tests/_bootstrap.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616
'includePaths' => [PROJECT_ROOT . '/src']
1717
]);
1818

19-
// force php to generate
20-
$GLOBALS['FORCE_PHP_GENERATE'] = true;
19+
// set mftf appplication context
20+
\Magento\FunctionalTestingFramework\Config\MftfApplicationConfig::create(
21+
true,
22+
\Magento\FunctionalTestingFramework\Config\MftfApplicationConfig::GENERATION_PHASE,
23+
true
24+
);
2125

2226
// Load needed framework env params
2327
$TEST_ENVS = [
@@ -42,6 +46,7 @@
4246

4347
defined('TESTS_BP') || define('TESTS_BP', __DIR__);
4448
defined('TESTS_MODULE_PATH') || define('TESTS_MODULE_PATH', TESTS_BP . $RELATIVE_TESTS_MODULE_PATH);
49+
defined('MAGENTO_BP') || define('MAGENTO_BP', __DIR__);
4550

4651
$utilDir = DIRECTORY_SEPARATOR . 'Util'. DIRECTORY_SEPARATOR . '*.php';
4752

dev/tests/unit/Magento/FunctionalTestFramework/Page/Handlers/PageObjectHandlerTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,25 @@ public function testGetPageObject()
5151
$this->assertNull($invalidPage);
5252
}
5353

54+
public function testGetEmptyPage()
55+
{
56+
$mockData = [
57+
"testPage1" => [
58+
"url" => "testURL1",
59+
"module" => "testModule1",
60+
"section" => [
61+
],
62+
"area" => "test"
63+
]];
64+
$this->setMockParserOutput($mockData);
65+
66+
// get pages
67+
$page = PageObjectHandler::getInstance()->getObject('testPage1');
68+
69+
// Empty page has been read in and gotten without an exception being thrown.
70+
$this->addToAssertionCount(1);
71+
}
72+
5473
/**
5574
* Function used to set mock for parser return and force init method to run between tests.
5675
*
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Tests\unit\Magento\FunctionalTestFramework\Suite\Handlers;
7+
8+
use AspectMock\Test as AspectMock;
9+
use Magento\FunctionalTestingFramework\ObjectManager\ObjectManager;
10+
use Magento\FunctionalTestingFramework\ObjectManagerFactory;
11+
use Magento\FunctionalTestingFramework\Suite\Handlers\SuiteObjectHandler;
12+
use Magento\FunctionalTestingFramework\Suite\Parsers\SuiteDataParser;
13+
use Magento\FunctionalTestingFramework\Test\Handlers\TestObjectHandler;
14+
use Magento\FunctionalTestingFramework\Test\Parsers\TestDataParser;
15+
use PHPUnit\Framework\TestCase;
16+
use tests\unit\Util\SuiteDataArrayBuilder;
17+
use tests\unit\Util\TestDataArrayBuilder;
18+
19+
class SuiteObjectHandlerTest extends TestCase
20+
{
21+
/**
22+
* Tests basic parsing and accesors of suite object and suite object supporting classes
23+
*/
24+
public function testGetSuiteObject()
25+
{
26+
$suiteDataArrayBuilder = new SuiteDataArrayBuilder();
27+
$mockData = $suiteDataArrayBuilder
28+
->withName('basicTestSuite')
29+
->withAfterHook()
30+
->withBeforeHook()
31+
->includeTests(['simpleTest'])
32+
->includeGroups(['group1'])
33+
->excludeTests(['group1Test2'])
34+
->excludeGroups(['group2'])
35+
->build();
36+
37+
$testDataArrayBuilder = new TestDataArrayBuilder();
38+
$mockSimpleTest = $testDataArrayBuilder
39+
->withName('simpleTest')
40+
->withTestActions()
41+
->build();
42+
43+
$mockGroup1Test1 = $testDataArrayBuilder
44+
->withName('group1Test1')
45+
->withAnnotations(['group' => [['value' => 'group1']]])
46+
->withTestActions()
47+
->build();
48+
49+
$mockGroup1Test2 = $testDataArrayBuilder
50+
->withName('group1Test2')
51+
->withAnnotations(['group' => [['value' => 'group1']]])
52+
->withTestActions()
53+
->build();
54+
55+
$mockGroup2Test1 = $testDataArrayBuilder
56+
->withName('group2Test1')
57+
->withAnnotations(['group' => [['value' => 'group2']]])
58+
->withTestActions()
59+
->build();
60+
61+
$mockTestData = ['tests' => array_merge($mockSimpleTest, $mockGroup1Test1, $mockGroup1Test2, $mockGroup2Test1)];
62+
$this->setMockTestAndSuiteParserOutput($mockTestData, $mockData);
63+
64+
// parse and retrieve suite object with mocked data
65+
$basicTestSuiteObj = SuiteObjectHandler::getInstance()->getObject('basicTestSuite');
66+
67+
// assert on created suite object
68+
$this->assertEquals($basicTestSuiteObj->getName(), 'basicTestSuite');
69+
$this->assertCount(2, $basicTestSuiteObj->getTests());
70+
$this->assertNotEmpty($basicTestSuiteObj->getBeforeHook());
71+
$this->assertNotEmpty($basicTestSuiteObj->getAfterHook());
72+
}
73+
74+
/**
75+
* Function used to set mock for parser return and force init method to run between tests.
76+
*
77+
* @param array $testData
78+
* @throws \Exception
79+
*/
80+
private function setMockTestAndSuiteParserOutput($testData, $suiteData)
81+
{
82+
// clear test object handler value to inject parsed content
83+
$property = new \ReflectionProperty(TestObjectHandler::class, 'testObjectHandler');
84+
$property->setAccessible(true);
85+
$property->setValue(null);
86+
87+
// clear suite object handler value to inject parsed content
88+
$property = new \ReflectionProperty(SuiteObjectHandler::class, 'SUITE_OBJECT_HANLDER_INSTANCE');
89+
$property->setAccessible(true);
90+
$property->setValue(null);
91+
92+
$mockDataParser = AspectMock::double(TestDataParser::class, ['readTestData' => $testData])->make();
93+
$mockSuiteDataParser = AspectMock::double(SuiteDataParser::class, ['readSuiteData' => $suiteData])->make();
94+
$instance = AspectMock::double(
95+
ObjectManager::class,
96+
['create' => function ($clazz) use ($mockDataParser, $mockSuiteDataParser) {
97+
if ($clazz == TestDataParser::class) {
98+
return $mockDataParser;
99+
}
100+
101+
if ($clazz == SuiteDataParser::class) {
102+
return $mockSuiteDataParser;
103+
}
104+
}]
105+
)->make();
106+
// bypass the private constructor
107+
AspectMock::double(ObjectManagerFactory::class, ['getObjectManager' => $instance]);
108+
}
109+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Tests\unit\Magento\FunctionalTestFramework\Test\Config;
7+
8+
use Magento\FunctionalTestingFramework\Exceptions\Collector\ExceptionCollector;
9+
use Magento\FunctionalTestingFramework\Test\Config\ActionGroupDom;
10+
use PHPUnit\Framework\TestCase;
11+
12+
class ActionGroupDomTest extends TestCase
13+
{
14+
/**
15+
* Test Action Group duplicate step key validation
16+
*/
17+
public function testActionGroupDomStepKeyValidation()
18+
{
19+
$sampleXml = "<actionGroups>
20+
<actionGroup name=\"actionGroupWithoutArguments\">
21+
<wait time=\"1\" stepKey=\"waitForNothing\" />
22+
<wait time=\"2\" stepKey=\"waitForNothing\" />
23+
</actionGroup>
24+
</actionGroups>";
25+
26+
$exceptionCollector = new ExceptionCollector();
27+
$actionDom = new ActionGroupDom($sampleXml, 'dupeStepKeyActionGroup.xml', $exceptionCollector);
28+
29+
$this->expectException(\Exception::class);
30+
$exceptionCollector->throwException();
31+
}
32+
}

dev/tests/unit/Magento/FunctionalTestFramework/Test/Objects/ActionObjectTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,36 @@ public function testResolveDataInUserInput()
255255
$this->assertEquals($expected, $actionObject->getCustomActionAttributes());
256256
}
257257

258+
/**
259+
* {{EntityDataObject.values}} should be replaced with ["value1","value2"]
260+
*/
261+
public function testResolveArrayData()
262+
{
263+
// Set up mocks
264+
$actionObject = new ActionObject('merge123', 'fillField', [
265+
'selector' => '#selector',
266+
'userInput' => '{{EntityDataObject.values}}'
267+
]);
268+
$entityDataObject = new EntityDataObject('EntityDataObject', 'test', [
269+
'values' => [
270+
'value1',
271+
'value2',
272+
'"My" Value'
273+
]
274+
], [], '', '');
275+
$this->mockDataHandlerWithData($entityDataObject);
276+
277+
// Call the method under test
278+
$actionObject->resolveReferences();
279+
280+
// Verify
281+
$expected = [
282+
'selector' => '#selector',
283+
'userInput' => '["value1","value2","\"My\" Value"]'
284+
];
285+
$this->assertEquals($expected, $actionObject->getCustomActionAttributes());
286+
}
287+
258288
/**
259289
* Action object should throw an exception if a reference to a parameterized selector has too few given args.
260290
*/

0 commit comments

Comments
 (0)