diff --git a/.gitignore b/.gitignore
index d39929c6f..63ea3d26e 100755
--- a/.gitignore
+++ b/.gitignore
@@ -15,4 +15,5 @@ codeception.yml
dev/tests/functional/MFTF.suite.yml
dev/tests/functional/_output
dev/mftf.log
-dev/tests/mftf.log
\ No newline at end of file
+dev/tests/mftf.log
+dev/tests/docs/*
\ No newline at end of file
diff --git a/dev/tests/_bootstrap.php b/dev/tests/_bootstrap.php
index 4b9d04442..31b4462f6 100644
--- a/dev/tests/_bootstrap.php
+++ b/dev/tests/_bootstrap.php
@@ -60,6 +60,28 @@
defined('TESTS_BP') || define('TESTS_BP', __DIR__);
defined('TESTS_MODULE_PATH') || define('TESTS_MODULE_PATH', TESTS_BP . $RELATIVE_TESTS_MODULE_PATH);
defined('MAGENTO_BP') || define('MAGENTO_BP', __DIR__);
+define('DOCS_OUTPUT_DIR',
+ FW_BP .
+ DIRECTORY_SEPARATOR .
+ "dev" .
+ DIRECTORY_SEPARATOR .
+ "tests" .
+ DIRECTORY_SEPARATOR .
+ "unit" .
+ DIRECTORY_SEPARATOR .
+ "_output"
+);
+define('RESOURCE_DIR',
+ FW_BP .
+ DIRECTORY_SEPARATOR .
+ "dev" .
+ DIRECTORY_SEPARATOR .
+ "tests" .
+ DIRECTORY_SEPARATOR .
+ "unit" .
+ DIRECTORY_SEPARATOR .
+ "Resources"
+);
$utilDir = DIRECTORY_SEPARATOR . 'Util'. DIRECTORY_SEPARATOR . '*.php';
diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Test/Util/ActionGroupAnnotationExtractorTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Test/Util/ActionGroupAnnotationExtractorTest.php
new file mode 100644
index 000000000..d56608894
--- /dev/null
+++ b/dev/tests/unit/Magento/FunctionalTestFramework/Test/Util/ActionGroupAnnotationExtractorTest.php
@@ -0,0 +1,104 @@
+setMockLoggingUtil();
+ }
+
+ /**
+ * Annotation extractor takes in raw array and condenses it to expected format
+ *
+ * @throws \Exception
+ */
+ public function testActionGroupExtractAnnotations()
+ {
+ // Test Data
+ $actionGroupAnnotations = [
+ "nodeName" => "annotations",
+ "description" => [
+ "nodeName" => "description",
+ "value" => "someDescription"
+ ],
+ "page" => [
+ "nodeName" => "page",
+ "value" => "somePage"
+ ]
+ ];
+ // Perform Test
+ $extractor = new ActionGroupAnnotationExtractor();
+ $returnedAnnotations = $extractor->extractAnnotations($actionGroupAnnotations, "fileName");
+
+ // Asserts
+
+ $this->assertEquals("somePage", $returnedAnnotations['page']);
+ $this->assertEquals("someDescription", $returnedAnnotations['description']);
+ }
+
+ /**
+ * Annotation extractor should throw warning when required annotations are missing
+ *
+ * @throws \Exception
+ */
+ public function testActionGroupMissingAnnotations()
+ {
+ // Action Group Data, missing page and description
+ $testAnnotations = [];
+ // Perform Test
+ $extractor = new ActionGroupAnnotationExtractor();
+ AspectMock::double($extractor, ['isCommandDefined' => true]);
+ $extractor->extractAnnotations($testAnnotations, "fileName");
+
+ // Asserts
+ TestLoggingUtil::getInstance()->validateMockLogStatement(
+ 'warning',
+ 'DEPRECATION: Action Group File fileName is missing required annotations.',
+ [
+ 'actionGroup' => 'fileName',
+ 'missingAnnotations' => "description, page"
+ ]
+ );
+ }
+
+ /**
+ * Annotation extractor should not throw warning when required
+ * annotations are missing if command is not generate:docs
+ *
+ * @throws \Exception
+ */
+ public function testActionGroupMissingAnnotationsNoWarning()
+ {
+ // Action Group Data, missing page and description
+ $testAnnotations = [];
+ // Perform Test
+ $extractor = new ActionGroupAnnotationExtractor();
+ $extractor->extractAnnotations($testAnnotations, "fileName");
+
+ // Asserts
+ TestLoggingUtil::getInstance()->validateMockLogEmpty();
+ }
+
+ /**
+ * After class functionality
+ * @return void
+ */
+ public static function tearDownAfterClass()
+ {
+ TestLoggingUtil::getInstance()->clearMockLoggingUtil();
+ }
+}
diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Util/DocGeneratorTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Util/DocGeneratorTest.php
new file mode 100644
index 000000000..ae61f37af
--- /dev/null
+++ b/dev/tests/unit/Magento/FunctionalTestFramework/Util/DocGeneratorTest.php
@@ -0,0 +1,131 @@
+ "somePage",
+ "description" => "someDescription"
+ ];
+ $actionGroupUnderTest = (new ActionGroupObjectBuilder())
+ ->withAnnotations($annotations)
+ ->withFilename("filename")
+ ->build();
+ $docGenerator = new DocGenerator();
+ $docGenerator->createDocumentation(
+ [$actionGroupUnderTest->getName() => $actionGroupUnderTest],
+ DOCS_OUTPUT_DIR,
+ true
+ );
+
+ $docFile = DOCS_OUTPUT_DIR . DIRECTORY_SEPARATOR . self::DOC_FILENAME . ".md";
+
+ $this->assertTrue(file_exists($docFile));
+
+ $this->assertFileEquals(
+ RESOURCE_DIR . DIRECTORY_SEPARATOR . "basicDocumentation.txt",
+ $docFile
+ );
+ }
+
+ /**
+ * Test to check creation of documentation when overwriting previous
+ *
+ * @throws \Exception
+ */
+ public function testCreateDocumentationWithOverwrite()
+ {
+ $annotations = [
+ "page" => "somePage",
+ "description" => "someDescription"
+ ];
+ $actionGroupUnderTest = (new ActionGroupObjectBuilder())
+ ->withAnnotations($annotations)
+ ->withFilename("filename")
+ ->build();
+ $docGenerator = new DocGenerator();
+ $docGenerator->createDocumentation(
+ [$actionGroupUnderTest->getName() => $actionGroupUnderTest],
+ DOCS_OUTPUT_DIR,
+ true
+ );
+
+ $annotations = [
+ "page" => "alteredPage",
+ "description" => "alteredDescription"
+ ];
+ $actionGroupUnderTest = (new ActionGroupObjectBuilder())
+ ->withAnnotations($annotations)
+ ->withFilename("filename")
+ ->build();
+ $docGenerator = new DocGenerator();
+ $docGenerator->createDocumentation(
+ [$actionGroupUnderTest->getName() => $actionGroupUnderTest],
+ DOCS_OUTPUT_DIR,
+ true
+ );
+
+ $docFile = DOCS_OUTPUT_DIR . DIRECTORY_SEPARATOR . self::DOC_FILENAME . ".md";
+
+ $this->assertTrue(file_exists($docFile));
+
+ $this->assertFileEquals(
+ RESOURCE_DIR . DIRECTORY_SEPARATOR . "alteredDocumentation.txt",
+ $docFile
+ );
+ }
+
+ /**
+ * Test for existing documentation without clean
+ *
+ * @throws \Exception
+ */
+ public function testCreateDocumentationNotCleanException()
+ {
+ $annotations = [
+ "page" => "somePage",
+ "description" => "someDescription"
+ ];
+ $actionGroupUnderTest = (new ActionGroupObjectBuilder())
+ ->withAnnotations($annotations)
+ ->withFilename("filename")
+ ->build();
+ $docGenerator = new DocGenerator();
+ $docGenerator->createDocumentation(
+ [$actionGroupUnderTest->getName() => $actionGroupUnderTest],
+ DOCS_OUTPUT_DIR,
+ true
+ );
+
+ $docFile = DOCS_OUTPUT_DIR . DIRECTORY_SEPARATOR . self::DOC_FILENAME . ".md";
+
+ $this->expectException(TestFrameworkException::class);
+ $this->expectExceptionMessage("$docFile already exists, please add --clean if you want to overwrite it.");
+
+ $docGenerator = new DocGenerator();
+ $docGenerator->createDocumentation(
+ [$actionGroupUnderTest->getName() => $actionGroupUnderTest],
+ DOCS_OUTPUT_DIR,
+ false
+ );
+ }
+}
diff --git a/dev/tests/unit/Resources/alteredDocumentation.txt b/dev/tests/unit/Resources/alteredDocumentation.txt
new file mode 100644
index 000000000..b55c30d6b
--- /dev/null
+++ b/dev/tests/unit/Resources/alteredDocumentation.txt
@@ -0,0 +1,16 @@
+#Action Group Information
+This documentation contains a list of all action groups on the pages on which they start
+
+##List of Pages
+- [ alteredPage ](#alteredPage)
+---
+
+##alteredPage
+
+###testActionGroupObject
+alteredDescription
+
+Located in:
+
+- filename
+***
diff --git a/dev/tests/unit/Resources/basicDocumentation.txt b/dev/tests/unit/Resources/basicDocumentation.txt
new file mode 100644
index 000000000..26a7fe719
--- /dev/null
+++ b/dev/tests/unit/Resources/basicDocumentation.txt
@@ -0,0 +1,16 @@
+#Action Group Information
+This documentation contains a list of all action groups on the pages on which they start
+
+##List of Pages
+- [ somePage ](#somePage)
+---
+
+##somePage
+
+###testActionGroupObject
+someDescription
+
+Located in:
+
+- filename
+***
diff --git a/dev/tests/unit/Util/ActionGroupObjectBuilder.php b/dev/tests/unit/Util/ActionGroupObjectBuilder.php
index f97d0465d..83537ab78 100644
--- a/dev/tests/unit/Util/ActionGroupObjectBuilder.php
+++ b/dev/tests/unit/Util/ActionGroupObjectBuilder.php
@@ -27,6 +27,13 @@ class ActionGroupObjectBuilder
*/
private $actionObjects = [];
+ /**
+ * Action Group Object Builder default entity annotations.
+ *
+ * @var array
+ */
+ private $annotations = [];
+
/**
* Action Group Object Builder default entity arguments.
*
@@ -41,6 +48,13 @@ class ActionGroupObjectBuilder
*/
private $extends = null;
+ /**
+ * Action Group Object Builder default filenames
+ *
+ * @var string
+ */
+ private $filename = [];
+
/**
* Setter for the Action Group Object name
*
@@ -53,6 +67,18 @@ public function withName($name)
return $this;
}
+ /**
+ * Setter for the Action Group Object annotations
+ *
+ * @param array $annotations
+ * @return ActionGroupObjectBuilder
+ */
+ public function withAnnotations($annotations)
+ {
+ $this->annotations = $annotations;
+ return $this;
+ }
+
/**
* Setter for the Action Group Object arguments
*
@@ -89,6 +115,18 @@ public function withExtendedAction($extendedActionGroup)
return $this;
}
+ /**
+ * Setter for the Action Group Object filename
+ *
+ * @param string $filename
+ * @return ActionGroupObjectBuilder
+ */
+ public function withFilename($filename)
+ {
+ $this->filename = $filename;
+ return $this;
+ }
+
/**
* ActionGroupObjectBuilder constructor.
*/
@@ -108,9 +146,11 @@ public function build()
{
return new ActionGroupObject(
$this->name,
+ $this->annotations,
$this->arguments,
$this->actionObjects,
- $this->extends
+ $this->extends,
+ $this->filename
);
}
}
diff --git a/dev/tests/unit/Util/MagentoTestCase.php b/dev/tests/unit/Util/MagentoTestCase.php
index 0aa153106..6a4e5d35b 100644
--- a/dev/tests/unit/Util/MagentoTestCase.php
+++ b/dev/tests/unit/Util/MagentoTestCase.php
@@ -14,6 +14,14 @@
*/
class MagentoTestCase extends TestCase
{
+ public static function setUpBeforeClass()
+ {
+ if (!self::fileExists(DOCS_OUTPUT_DIR)) {
+ mkdir(DOCS_OUTPUT_DIR, 0755, true);
+ }
+ parent::setUpBeforeClass();
+ }
+
/**
* Teardown for removing AspectMock Double References
* @return void
@@ -21,5 +29,9 @@ class MagentoTestCase extends TestCase
public static function tearDownAfterClass()
{
AspectMock::clean();
+ array_map('unlink', glob(DOCS_OUTPUT_DIR . DIRECTORY_SEPARATOR . "*"));
+ if (file_exists(DOCS_OUTPUT_DIR)) {
+ rmdir(DOCS_OUTPUT_DIR);
+ }
}
}
diff --git a/dev/tests/unit/Util/TestLoggingUtil.php b/dev/tests/unit/Util/TestLoggingUtil.php
index 6d2e4b964..7becc609a 100644
--- a/dev/tests/unit/Util/TestLoggingUtil.php
+++ b/dev/tests/unit/Util/TestLoggingUtil.php
@@ -10,7 +10,6 @@
use Magento\FunctionalTestingFramework\Util\Logger\LoggingUtil;
use Magento\FunctionalTestingFramework\Util\Logger\MftfLogger;
use Monolog\Handler\TestHandler;
-use Monolog\Logger;
use PHPUnit\Framework\Assert;
class TestLoggingUtil extends Assert
@@ -66,6 +65,12 @@ public function setMockLoggingUtil()
$property->setValue($mockLoggingUtil);
}
+ public function validateMockLogEmpty()
+ {
+ $records = $this->testLogHandler->getRecords();
+ $this->assertTrue(empty($records));
+ }
+
/**
* Function which validates messages have been logged as intended during test execution.
*
diff --git a/docs/commands/mftf.md b/docs/commands/mftf.md
index e418f7970..998426564 100644
--- a/docs/commands/mftf.md
+++ b/docs/commands/mftf.md
@@ -67,6 +67,13 @@ vendor/bin/mftf run:failed
This command cleans up the previously generated tests; generates and runs the tests listed in `dev/tests/acceptance/tests/_output/failed`.
For more details about `failed`, refer to [Reporting][].
+### Generate documentation for action groups
+```bash
+vendor/bin/mftf generate:docs
+```
+
+This command generates documentation for action groups.
+
## Reference
### `build:project`
@@ -220,6 +227,33 @@ vendor/bin/mftf generate:urn-catalog [--force] [/dev/tests/docs/documentation.md`.
+
+#### Usage
+
+```bash
+vendor/bin/mftf generate:docs [--clean] [--output=/path/to/alternate/dir]
+```
+
+#### Options
+
+| Option | Description |
+| ------------- | --------------------------------------------------------------------- |
+| `-c, --clean` | Overwrites previously existing documentation |
+| `-o, --output` | Changes the default output directory to a user specified directory |
+
+#### Example
+
+```bash
+vendor/bin/mftf generate:docs --clean
+```
+
+
### `reset`
#### Description
diff --git a/src/Magento/FunctionalTestingFramework/Console/CommandList.php b/src/Magento/FunctionalTestingFramework/Console/CommandList.php
index 7623bea66..5bcf1ed31 100644
--- a/src/Magento/FunctionalTestingFramework/Console/CommandList.php
+++ b/src/Magento/FunctionalTestingFramework/Console/CommandList.php
@@ -11,6 +11,7 @@
/**
* Class CommandList has a list of commands.
* @codingStandardsIgnoreFile
+ * @SuppressWarnings(PHPMD)
*/
class CommandList implements CommandListInterface
{
@@ -38,7 +39,8 @@ public function __construct(array $commands = [])
'run:failed' => new RunTestFailedCommand(),
'setup:env' => new SetupEnvCommand(),
'upgrade:tests' => new UpgradeTestsCommand(),
- 'static-checks' => new StaticChecksCommand(),
+ 'generate:docs' => new GenerateDocsCommand(),
+ 'static-checks' => new StaticChecksCommand()
] + $commands;
}
diff --git a/src/Magento/FunctionalTestingFramework/Console/GenerateDocsCommand.php b/src/Magento/FunctionalTestingFramework/Console/GenerateDocsCommand.php
new file mode 100644
index 000000000..db77bc74f
--- /dev/null
+++ b/src/Magento/FunctionalTestingFramework/Console/GenerateDocsCommand.php
@@ -0,0 +1,85 @@
+setName('generate:docs')
+ ->setDescription('This command generates documentation for created MFTF files.')
+ ->addOption(
+ "output",
+ 'o',
+ InputOption::VALUE_REQUIRED,
+ 'Output Directory'
+ )->addOption(
+ "clean",
+ 'c',
+ InputOption::VALUE_NONE,
+ 'Clean Output Directory'
+ )->addOption(
+ "force",
+ 'f',
+ InputOption::VALUE_NONE,
+ 'Force Document Generation For All Action Groups'
+ );
+ }
+
+ /**
+ * Executes the current command.
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return void
+ * @throws TestFrameworkException
+ * @throws \Magento\FunctionalTestingFramework\Exceptions\TestReferenceException
+ * @throws \Magento\FunctionalTestingFramework\Exceptions\XmlException
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ defined('COMMAND') || define('COMMAND', 'generate:docs');
+ $config = $input->getOption('output');
+ $clean = $input->getOption('clean');
+ $force = $input->getOption('force');
+
+ MftfApplicationConfig::create(
+ $force,
+ MftfApplicationConfig::GENERATION_PHASE,
+ false,
+ false
+ );
+
+ $allActionGroups = ActionGroupObjectHandler::getInstance()->getAllObjects();
+ $docGenerator = new DocGenerator();
+ $docGenerator->createDocumentation($allActionGroups, $config, $clean);
+
+ $output->writeln("Generate Docs Command Run");
+
+ if (empty($config)) {
+ $output->writeln("Output to ". DocGenerator::DEFAULT_OUTPUT_DIR);
+ } else {
+ $output->writeln("Output to ". $config);
+ }
+ }
+}
diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php
index eec6d74b7..ef2e11c03 100644
--- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php
+++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php
@@ -7,8 +7,6 @@
namespace Magento\FunctionalTestingFramework\Test\Objects;
use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException;
-use Magento\FunctionalTestingFramework\Test\Handlers\ActionGroupObjectHandler;
-use Magento\FunctionalTestingFramework\Test\Util\ActionGroupObjectExtractor;
use Magento\FunctionalTestingFramework\Test\Util\ActionMergeUtil;
use Magento\FunctionalTestingFramework\Test\Util\ObjectExtension;
@@ -19,6 +17,8 @@ class ActionGroupObject
{
const ACTION_GROUP_ORIGIN_NAME = "actionGroupName";
const ACTION_GROUP_ORIGIN_TEST_REF = "testInvocationRef";
+ const ACTION_GROUP_DESCRIPTION = "description";
+ const ACTION_GROUP_PAGE = "page";
const ACTION_GROUP_CONTEXT_START = "Entering Action Group ";
const ACTION_GROUP_CONTEXT_END = "Exiting Action Group ";
const STEPKEY_REPLACEMENT_ENABLED_TYPES = [
@@ -66,6 +66,13 @@ class ActionGroupObject
*/
private $arguments;
+ /**
+ * An array used to store annotation information to values
+ *
+ * @var array
+ */
+ private $annotations;
+
/**
* String of parent Action Group
*
@@ -84,12 +91,13 @@ class ActionGroupObject
* ActionGroupObject constructor.
*
* @param string $name
+ * @param array $annotations
* @param ArgumentObject[] $arguments
* @param array $actions
* @param string $parentActionGroup
* @param string $filename
*/
- public function __construct($name, $arguments, $actions, $parentActionGroup, $filename = null)
+ public function __construct($name, $annotations, $arguments, $actions, $parentActionGroup, $filename = null)
{
$this->varAttributes = array_merge(
ActionObject::SELECTOR_ENABLED_ATTRIBUTES,
@@ -97,6 +105,7 @@ public function __construct($name, $arguments, $actions, $parentActionGroup, $fi
);
$this->varAttributes[] = ActionObject::ACTION_ATTRIBUTE_URL;
$this->name = $name;
+ $this->annotations = $annotations;
$this->arguments = $arguments;
$this->parsedActions = $actions;
$this->parentActionGroup = $parentActionGroup;
@@ -462,6 +471,16 @@ public function getArguments()
return $this->arguments;
}
+ /**
+ * Getter for the Action Group Annotations
+ *
+ * @return array
+ */
+ public function getAnnotations()
+ {
+ return $this->annotations;
+ }
+
/**
* Searches through ActionGroupObject's arguments and returns first argument wi
* @param string $name
diff --git a/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupAnnotationExtractor.php b/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupAnnotationExtractor.php
new file mode 100644
index 000000000..b6e89fd44
--- /dev/null
+++ b/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupAnnotationExtractor.php
@@ -0,0 +1,86 @@
+stripDescriptorTags($testAnnotations, parent::NODE_NAME);
+
+ foreach ($annotations as $annotationKey => $annotationData) {
+ $annotationObjects[$annotationKey] = $annotationData[parent::ANNOTATION_VALUE];
+ }
+ // TODO: Remove this when all action groups have annotations
+ if ($this->isCommandDefined()) {
+ $this->validateMissingAnnotations($annotationObjects, $filename);
+ }
+
+ return $annotationObjects;
+ }
+
+ /**
+ * Validates given annotations against list of required annotations.
+ *
+ * @param array $annotationObjects
+ * @return void
+ * @throws \Exception
+ */
+ private function validateMissingAnnotations($annotationObjects, $filename)
+ {
+ $missingAnnotations = [];
+
+ foreach (self::ACTION_GROUP_REQUIRED_ANNOTATIONS as $REQUIRED_ANNOTATION) {
+ if (!array_key_exists($REQUIRED_ANNOTATION, $annotationObjects)) {
+ $missingAnnotations[] = $REQUIRED_ANNOTATION;
+ }
+ }
+
+ if (!empty($missingAnnotations)) {
+ $message = "Action Group File {$filename} is missing required annotations.";
+ LoggingUtil::getInstance()->getLogger(ActionObject::class)->deprecation(
+ $message,
+ ["actionGroup" => $filename, "missingAnnotations" => implode(", ", $missingAnnotations)]
+ );
+ }
+ }
+
+ /**
+ * Checks if command is defined as generate:docs
+ *
+ * @return boolean
+ */
+ private function isCommandDefined()
+ {
+ if (defined('COMMAND') and COMMAND == self::GENERATE_DOCS_COMMAND) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php b/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php
index 6d7e67b38..74665cf75 100644
--- a/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php
+++ b/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php
@@ -18,6 +18,7 @@ class ActionGroupObjectExtractor extends BaseObjectExtractor
{
const DEFAULT_VALUE = 'defaultValue';
const ACTION_GROUP_ARGUMENTS = 'arguments';
+ const ACTION_GROUP_ANNOTATIONS = 'annotations';
const FILENAME = 'filename';
const ACTION_GROUP_INSERT_BEFORE = "insertBefore";
const ACTION_GROUP_INSERT_AFTER = "insertAfter";
@@ -30,12 +31,20 @@ class ActionGroupObjectExtractor extends BaseObjectExtractor
*/
private $actionObjectExtractor;
+ /**
+ * Annotation Extractor object
+ *
+ * @var AnnotationExtractor
+ */
+ private $annotationExtractor;
+
/**
* ActionGroupObjectExtractor constructor.
*/
public function __construct()
{
$this->actionObjectExtractor = new ActionObjectExtractor();
+ $this->annotationExtractor = new ActionGroupAnnotationExtractor();
}
/**
@@ -55,6 +64,7 @@ public function extractActionGroup($actionGroupData)
self::NODE_NAME,
self::ACTION_GROUP_ARGUMENTS,
self::NAME,
+ self::ACTION_GROUP_ANNOTATIONS,
self::FILENAME,
self::ACTION_GROUP_INSERT_BEFORE,
self::ACTION_GROUP_INSERT_AFTER,
@@ -62,6 +72,16 @@ public function extractActionGroup($actionGroupData)
);
// TODO filename is now available to the ActionGroupObject, integrate this into debug and error statements
+
+ try {
+ $annotations = $this->annotationExtractor->extractAnnotations(
+ $actionGroupData[self::ACTION_GROUP_ANNOTATIONS] ?? [],
+ $actionGroupData[self::FILENAME]
+ );
+ } catch (\Exception $error) {
+ throw new XmlException($error->getMessage() . " in Action Group " . $actionGroupData[self::FILENAME]);
+ }
+
try {
$actions = $this->actionObjectExtractor->extractActions($actionData);
} catch (\Exception $error) {
@@ -74,6 +94,7 @@ public function extractActionGroup($actionGroupData)
return new ActionGroupObject(
$actionGroupData[self::NAME],
+ $annotations,
$arguments,
$actions,
$actionGroupReference,
diff --git a/src/Magento/FunctionalTestingFramework/Test/Util/ObjectExtensionUtil.php b/src/Magento/FunctionalTestingFramework/Test/Util/ObjectExtensionUtil.php
index 4c3949ef3..91617b1e2 100644
--- a/src/Magento/FunctionalTestingFramework/Test/Util/ObjectExtensionUtil.php
+++ b/src/Magento/FunctionalTestingFramework/Test/Util/ObjectExtensionUtil.php
@@ -129,6 +129,7 @@ public function extendActionGroup($actionGroupObject)
// Create new Action Group object to return
$extendedActionGroup = new ActionGroupObject(
$actionGroupObject->getName(),
+ $actionGroupObject->getAnnotations(),
$extendedArguments,
$newActions,
$actionGroupObject->getParentName(),
diff --git a/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd b/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd
index 619d21e9f..616995531 100644
--- a/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd
+++ b/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd
@@ -30,6 +30,14 @@
+
+
+
+
+
+
+
+
diff --git a/src/Magento/FunctionalTestingFramework/Util/DocGenerator.php b/src/Magento/FunctionalTestingFramework/Util/DocGenerator.php
new file mode 100644
index 000000000..9846cded5
--- /dev/null
+++ b/src/Magento/FunctionalTestingFramework/Util/DocGenerator.php
@@ -0,0 +1,143 @@
+ $object) {
+ $annotations = $object->getAnnotations();
+ $filenames = explode(',', $object->getFilename());
+ $arguments = $object->getArguments();
+
+ $info = [
+ actionGroupObject::ACTION_GROUP_DESCRIPTION => $annotations[actionGroupObject::ACTION_GROUP_DESCRIPTION]
+ ?? 'NO_DESCRIPTION_SPECIFIED',
+ self::FILENAMES => $filenames,
+ ActionGroupObjectExtractor::ACTION_GROUP_ARGUMENTS => $arguments
+ ];
+ $pageGroups = array_merge_recursive(
+ $pageGroups,
+ [$annotations[ActionGroupObject::ACTION_GROUP_PAGE] ?? 'NO_PAGE_SPECIFIED' => [$name => $info]]
+ );
+ }
+
+ ksort($pageGroups);
+ foreach ($pageGroups as $page => $groups) {
+ ksort($groups);
+ $pageGroups[$page] = $groups;
+ }
+
+ $markdown = $this->transformToMarkdown($pageGroups);
+
+ file_put_contents($filePath, $markdown);
+ }
+
+ /**
+ * This creates html documentation for objects passed in
+ *
+ * @param array $annotationList
+ * @return string
+ */
+ private function transformToMarkdown($annotationList)
+ {
+ $markdown = "#Action Group Information" . PHP_EOL;
+ $markdown .= "This documentation contains a list of all" .
+ " action groups on the pages on which they start" .
+ PHP_EOL .
+ PHP_EOL;
+
+ $markdown .= "##List of Pages" . PHP_EOL;
+ foreach ($annotationList as $group => $objects) {
+ $markdown .= "- [ $group ](#$group)" . PHP_EOL;
+ }
+ $markdown .= "---" . PHP_EOL;
+ foreach ($annotationList as $group => $objects) {
+ $markdown .= "" . PHP_EOL;
+ $markdown .= "##$group" . PHP_EOL . PHP_EOL;
+ foreach ($objects as $name => $annotations) {
+ $markdown .= "###$name" . PHP_EOL;
+ $markdown .= $annotations[actionGroupObject::ACTION_GROUP_DESCRIPTION] . PHP_EOL . PHP_EOL;
+ if (!empty($annotations[ActionGroupObjectExtractor::ACTION_GROUP_ARGUMENTS])) {
+ $markdown .= "Action Group Arguments:" . PHP_EOL . PHP_EOL;
+ $markdown .= "| Name | Type |" . PHP_EOL;
+ $markdown .= "| --- | --- |" . PHP_EOL;
+ foreach ($annotations[ActionGroupObjectExtractor::ACTION_GROUP_ARGUMENTS] as $argument) {
+ $argumentName = $argument->getName();
+ $argumentType = $argument->getDataType();
+ $markdown .= "| $argumentName | $argumentType |" . PHP_EOL;
+ }
+ $markdown .= PHP_EOL;
+ }
+ $markdown .= "Located in:" . PHP_EOL;
+ foreach ($annotations[self::FILENAMES] as $filename) {
+ $relativeFilename = str_replace(MAGENTO_BP . DIRECTORY_SEPARATOR, "", $filename);
+ $markdown .= PHP_EOL . "- $relativeFilename";
+ }
+ $markdown .= PHP_EOL . "***" . PHP_EOL;
+ }
+ }
+ return $markdown;
+ }
+}