diff --git a/RoboFile.php b/RoboFile.php
deleted file mode 100644
index c0af4c72c..000000000
--- a/RoboFile.php
+++ /dev/null
@@ -1,214 +0,0 @@
-_exec('cp -vn .env.example .env');
- $this->_exec('cp -vf codeception.dist.yml codeception.yml');
- $this->_exec('cp -vf dev' . DIRECTORY_SEPARATOR . 'tests'. DIRECTORY_SEPARATOR . 'functional' . DIRECTORY_SEPARATOR .'MFTF.suite.dist.yml dev' . DIRECTORY_SEPARATOR . 'tests'. DIRECTORY_SEPARATOR . 'functional' . DIRECTORY_SEPARATOR .'MFTF.suite.yml');
- }
-
- /**
- * Duplicate the Example configuration files for the Project.
- * Build the Codeception project.
- *
- * @return void
- */
- function buildProject()
- {
- $this->writeln("This command will be removed in MFTF v3.0.0. Please use bin/mftf build:project instead.\n");
- $this->cloneFiles();
- $this->_exec('vendor'. DIRECTORY_SEPARATOR .'bin'. DIRECTORY_SEPARATOR .'codecept build');
- }
-
- /**
- * Generate all Tests in PHP.
- *
- * @param array $tests
- * @param array $opts
- * @return void
- */
- function generateTests(array $tests, $opts = ['config' => null, 'force' => true, 'nodes' => null, 'debug' => false])
- {
- require 'dev' . DIRECTORY_SEPARATOR . 'tests'. DIRECTORY_SEPARATOR . 'functional' . DIRECTORY_SEPARATOR . '_bootstrap.php';
- $GLOBALS['GENERATE_TESTS'] = true;
- if (!$this->isProjectBuilt()) {
- $this->say("Please run bin/mftf build:project and configure your environment (.env) first.");
- exit(\Robo\Result::EXITCODE_ERROR);
- }
- $testsObjects = [];
- foreach ($tests as $test) {
- $testsObjects[] = Magento\FunctionalTestingFramework\Test\Handlers\TestObjectHandler::getInstance()->getObject($test);
- }
- if ($opts['force']) {
- $GLOBALS['FORCE_PHP_GENERATE'] = true;
- }
- $testsReferencedInSuites = \Magento\FunctionalTestingFramework\Suite\SuiteGenerator::getInstance()->generateAllSuites($opts['config']);
- \Magento\FunctionalTestingFramework\Util\TestGenerator::getInstance(null, $testsObjects, $opts['debug'])->createAllTestFiles($opts['config'], $opts['nodes'], $testsReferencedInSuites);
- $this->say("Generate Tests Command Run");
- }
-
- /**
- * Check if MFTF has been properly configured
- * @return bool
- */
- private function isProjectBuilt()
- {
- $actorFile = __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Magento' . DIRECTORY_SEPARATOR . 'FunctionalTestingFramework' . DIRECTORY_SEPARATOR . '_generated' . DIRECTORY_SEPARATOR . 'AcceptanceTesterActions.php';
-
- $login = !empty(getenv('MAGENTO_ADMIN_USERNAME'));
- $password = !empty(getenv('MAGENTO_ADMIN_PASSWORD'));
- $baseUrl = !empty(getenv('MAGENTO_BASE_URL'));
- $backendName = !empty(getenv('MAGENTO_BACKEND_NAME'));
- $test = (file_exists($actorFile) && $login && $password && $baseUrl && $backendName);
- return $test;
- }
-
- /**
- * Generate a suite based on name(s) passed in as args.
- *
- * @param array $args
- * @throws Exception
- * @return void
- */
- function generateSuite(array $args)
- {
- if (empty($args)) {
- throw new Exception("Please provide suite name(s) after generate:suite command");
- }
-
- require 'dev' . DIRECTORY_SEPARATOR . 'tests'. DIRECTORY_SEPARATOR . 'functional' . DIRECTORY_SEPARATOR . '_bootstrap.php';
- $sg = \Magento\FunctionalTestingFramework\Suite\SuiteGenerator::getInstance();
-
- foreach ($args as $arg) {
- $sg->generateSuite($arg);
- }
- }
-
- /**
- * Run all MFTF tests.
- *
- * @return void
- */
- function mftf()
- {
- $this->_exec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run MFTF --skip-group skip');
- }
-
- /**
- * Run all Tests with the specified @group tag, excluding @group 'skip'.
- *
- * @param string $args
- * @return void
- */
- function group($args = '')
- {
- $this->taskExec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run --verbose --steps --skip-group skip --group')->args($args)->run();
- }
-
- /**
- * Run all Functional tests located under the Directory Path provided.
- *
- * @param string $args
- * @return void
- */
- function folder($args = '')
- {
- $this->taskExec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run ')->args($args)->run();
- }
-
- /**
- * Run all Tests marked with the @group tag 'example'.
- *
- * @return void
- */
- function example()
- {
- $this->_exec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run --group example --skip-group skip');
- }
-
- /**
- * Generate the HTML for the Allure report based on the Test XML output - Allure v1.4.X
- *
- * @return \Robo\Result
- */
- function allure1Generate()
- {
- return $this->_exec('allure generate tests'. DIRECTORY_SEPARATOR .'_output'. DIRECTORY_SEPARATOR .'allure-results'. DIRECTORY_SEPARATOR .' -o tests'. DIRECTORY_SEPARATOR .'_output'. DIRECTORY_SEPARATOR .'allure-report'. DIRECTORY_SEPARATOR .'');
- }
-
- /**
- * Generate the HTML for the Allure report based on the Test XML output - Allure v2.3.X
- *
- * @return \Robo\Result
- */
- function allure2Generate()
- {
- return $this->_exec('allure generate tests'. DIRECTORY_SEPARATOR .'_output'. DIRECTORY_SEPARATOR .'allure-results'. DIRECTORY_SEPARATOR .' --output tests'. DIRECTORY_SEPARATOR .'_output'. DIRECTORY_SEPARATOR .'allure-report'. DIRECTORY_SEPARATOR .' --clean');
- }
-
- /**
- * Open the HTML Allure report - Allure v1.4.X
- *
- * @return void
- */
- function allure1Open()
- {
- $this->_exec('allure report open --report-dir tests'. DIRECTORY_SEPARATOR .'_output'. DIRECTORY_SEPARATOR .'allure-report'. DIRECTORY_SEPARATOR .'');
- }
-
- /**
- * Open the HTML Allure report - Allure v2.3.X
- *
- * @return void
- */
- function allure2Open()
- {
- $this->_exec('allure open --port 0 tests'. DIRECTORY_SEPARATOR .'_output'. DIRECTORY_SEPARATOR .'allure-report'. DIRECTORY_SEPARATOR .'');
- }
-
- /**
- * Generate and open the HTML Allure report - Allure v1.4.X
- *
- * @return void
- */
- function allure1Report()
- {
- $result1 = $this->allure1Generate();
-
- if ($result1->wasSuccessful()) {
- $this->allure1Open();
- }
- }
-
- /**
- * Generate and open the HTML Allure report - Allure v2.3.X
- *
- * @return void
- */
- function allure2Report()
- {
- $result1 = $this->allure2Generate();
-
- if ($result1->wasSuccessful()) {
- $this->allure2Open();
- }
- }
-}
diff --git a/bin/mftf b/bin/mftf
index 623e3bc61..b8c1cce80 100755
--- a/bin/mftf
+++ b/bin/mftf
@@ -11,13 +11,27 @@ if (PHP_SAPI !== 'cli') {
exit(1);
}
+$autoload_path = realpath(__DIR__ . '/../../../autoload.php');
+$test_bootstrap_path = realpath(__DIR__ . '/../dev/tests/functional/_bootstrap.php');
+
+if (file_exists($autoload_path)) {
+ require_once $autoload_path;
+} else {
+ require_once $test_bootstrap_path;
+}
+
+
try {
- require_once __DIR__ . '/../bootstrap.php';
$application = new Symfony\Component\Console\Application();
$application->setName('Magento Functional Testing Framework CLI');
$application->setVersion('1.0.0');
$application->add(new Magento\FunctionalTestingFramework\Console\SetupEnvCommand());
+ $application->add(new Magento\FunctionalTestingFramework\Console\CleanProjectCommand());
$application->add(new Magento\FunctionalTestingFramework\Console\BuildProjectCommand());
+ $application->add(new Magento\FunctionalTestingFramework\Console\GenerateSuiteCommand());
+ $application->add(new Magento\FunctionalTestingFramework\Console\GenerateTestsCommand());
+ $application->add(new Magento\FunctionalTestingFramework\Console\RunTestGroupCommand());
+ $application->add(new Magento\FunctionalTestingFramework\Console\RunTestCommand());
$application->run();
} catch (\Exception $e) {
while ($e) {
diff --git a/bootstrap.php b/bootstrap.php
deleted file mode 100644
index 7a708e8a8..000000000
--- a/bootstrap.php
+++ /dev/null
@@ -1,8 +0,0 @@
-init([
'debug' => true,
- 'includePaths' => [PROJECT_ROOT . '/src'],
+ 'includePaths' => [PROJECT_ROOT . DIRECTORY_SEPARATOR . 'src'],
'cacheDir' => PROJECT_ROOT .
DIRECTORY_SEPARATOR .
'dev' .
diff --git a/dev/tests/functional/MFTF/_bootstrap.php b/dev/tests/functional/MFTF/_bootstrap.php
deleted file mode 100755
index 6a524e867..000000000
--- a/dev/tests/functional/MFTF/_bootstrap.php
+++ /dev/null
@@ -1,7 +0,0 @@
-load();
-
- if (array_key_exists('TESTS_MODULE_PATH', $_ENV) xor array_key_exists('TESTS_BP', $_ENV)) {
- throw new Exception('You must define both parameters TESTS_BP and TESTS_MODULE_PATH or neither parameter');
- }
-
- foreach ($_ENV as $key => $var) {
- defined($key) || define($key, $var);
- }
-}
defined('FW_BP') || define('FW_BP', PROJECT_ROOT);
// add the debug flag here
@@ -29,7 +16,17 @@
xdebug_disable();
}
-$RELATIVE_TESTS_MODULE_PATH = '/MFTF/FunctionalTest';
+$RELATIVE_TESTS_MODULE_PATH = '/tests/functional/tests/MFTF';
-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', PROJECT_ROOT);
+defined('TESTS_BP') || define('TESTS_BP', dirname(dirname(__DIR__)));
+defined('TESTS_MODULE_PATH') || define('TESTS_MODULE_PATH', realpath(TESTS_BP . $RELATIVE_TESTS_MODULE_PATH));
+
+if (file_exists(TESTS_BP . DIRECTORY_SEPARATOR . '.env')) {
+ $env = new \Dotenv\Loader(TESTS_BP . DIRECTORY_SEPARATOR . '.env');
+ $env->load();
+
+ foreach ($_ENV as $key => $var) {
+ defined($key) || define($key, $var);
+ }
+}
diff --git a/dev/tests/functional/MFTF/FunctionalTest/DevDocs/Page/MFTFDocPage.xml b/dev/tests/functional/tests/MFTF/DevDocs/Page/MFTFDocPage.xml
similarity index 100%
rename from dev/tests/functional/MFTF/FunctionalTest/DevDocs/Page/MFTFDocPage.xml
rename to dev/tests/functional/tests/MFTF/DevDocs/Page/MFTFDocPage.xml
diff --git a/dev/tests/functional/MFTF/FunctionalTest/DevDocs/Section/ContentSection.xml b/dev/tests/functional/tests/MFTF/DevDocs/Section/ContentSection.xml
similarity index 100%
rename from dev/tests/functional/MFTF/FunctionalTest/DevDocs/Section/ContentSection.xml
rename to dev/tests/functional/tests/MFTF/DevDocs/Section/ContentSection.xml
diff --git a/dev/tests/functional/MFTF/FunctionalTest/DevDocs/Test/DevDocsTest.xml b/dev/tests/functional/tests/MFTF/DevDocs/Test/DevDocsTest.xml
similarity index 100%
rename from dev/tests/functional/MFTF/FunctionalTest/DevDocs/Test/DevDocsTest.xml
rename to dev/tests/functional/tests/MFTF/DevDocs/Test/DevDocsTest.xml
diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php
index 8eb486144..d6790f00e 100644
--- a/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php
+++ b/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php
@@ -23,6 +23,17 @@
class SuiteGeneratorTest extends TestCase
{
+ /**
+ * Setup entry append and clear for Suite Generator
+ */
+ public static function setUpBeforeClass()
+ {
+ AspectMock::double(SuiteGenerator::class, [
+ 'clearPreviousSessionConfigEntries' => null,
+ 'appendEntriesToConfig' => null
+ ]);
+ }
+
/**
* Tests generating a single suite given a set of parsed test data
* @throws \Exception
@@ -169,6 +180,5 @@ private function setMockTestAndSuiteParserOutput($testData, $suiteData)
$property = new \ReflectionProperty(SuiteGenerator::class, 'groupClassGenerator');
$property->setAccessible(true);
$property->setValue($instance, $instance);
-
}
}
diff --git a/dev/tests/verification/Tests/SuiteGenerationTest.php b/dev/tests/verification/Tests/SuiteGenerationTest.php
index 5f2d3a6d2..4024329f1 100644
--- a/dev/tests/verification/Tests/SuiteGenerationTest.php
+++ b/dev/tests/verification/Tests/SuiteGenerationTest.php
@@ -8,15 +8,17 @@
use Magento\FunctionalTestingFramework\Suite\SuiteGenerator;
use Magento\FunctionalTestingFramework\Util\Filesystem\DirSetupUtil;
+use Magento\FunctionalTestingFramework\Util\Manifest\DefaultTestManifest;
use Magento\FunctionalTestingFramework\Util\Manifest\ParallelTestManifest;
use Magento\FunctionalTestingFramework\Util\Manifest\TestManifestFactory;
+use PHPUnit\Util\Filesystem;
use Symfony\Component\Yaml\Yaml;
use tests\util\MftfTestCase;
class SuiteGenerationTest extends MftfTestCase
{
const RESOURCES_DIR = TESTS_BP . DIRECTORY_SEPARATOR . 'verification' . DIRECTORY_SEPARATOR . 'Resources';
- const CONFIG_YML_FILE = FW_BP . DIRECTORY_SEPARATOR . SuiteGenerator::YAML_CODECEPTION_CONFIG_FILENAME;
+ const CONFIG_YML_FILE = TESTS_BP . DIRECTORY_SEPARATOR . SuiteGenerator::YAML_CODECEPTION_CONFIG_FILENAME;
const GENERATE_RESULT_DIR = TESTS_BP .
DIRECTORY_SEPARATOR .
"verification" .
@@ -24,13 +26,6 @@ class SuiteGenerationTest extends MftfTestCase
"_generated" .
DIRECTORY_SEPARATOR;
- /**
- * Flag to track existence of config.yml file
- *
- * @var bool
- */
- private static $YML_EXISTS_FLAG = false;
-
/**
* Array which stores state of any existing config.yml groups
*
@@ -43,18 +38,20 @@ class SuiteGenerationTest extends MftfTestCase
*/
public static function setUpBeforeClass()
{
- if (file_exists(self::CONFIG_YML_FILE)) {
- self::$YML_EXISTS_FLAG = true;
- return;
- }
-
// destroy _generated if it exists
if (file_exists(self::GENERATE_RESULT_DIR)) {
DirSetupUtil::rmdirRecursive(self::GENERATE_RESULT_DIR);
}
+ }
- $configYml = fopen(self::CONFIG_YML_FILE, "w");
- fclose($configYml);
+ public function setUp()
+ {
+ // copy config yml file to test dir
+ $fileSystem = new \Symfony\Component\Filesystem\Filesystem();
+ $fileSystem->copy(
+ realpath(FW_BP . '/etc/config/codeception.dist.yml'),
+ self::CONFIG_YML_FILE
+ );
}
/**
@@ -200,7 +197,6 @@ public function testSuiteGenerationHooks()
self::RESOURCES_PATH . DIRECTORY_SEPARATOR . $groupName . ".txt",
$groupFile
);
-
}
/**
@@ -219,7 +215,7 @@ public function testSuiteGenerationSingleRun()
];
//createParallelManifest
- /** @var ParallelTestManifest $parallelManifest */
+ /** @var DefaultTestManifest $parallelManifest */
$singleRunManifest = TestManifestFactory::makeManifest("singleRun", ["functionalSuite2" => []]);
// Generate the Suite
@@ -246,7 +242,7 @@ public function testSuiteGenerationSingleRun()
$this->assertTrue(in_array($expectedFile, $dirContents));
}
- $expectedManifest = "dev/tests/verification/_generated/default/" . PHP_EOL . "-g functionalSuite2" . PHP_EOL;
+ $expectedManifest = "verification/_generated/default/" . PHP_EOL . "-g functionalSuite2" . PHP_EOL;
$this->assertEquals($expectedManifest, file_get_contents(self::getManifestFilePath()));
}
@@ -257,26 +253,13 @@ public function testSuiteGenerationSingleRun()
*/
public function tearDown()
{
- // restore config if we see there was an original codeception.yml file
- if (self::$YML_EXISTS_FLAG) {
- $yml = Yaml::parse(file_get_contents(self::CONFIG_YML_FILE));
- foreach (self::$TEST_GROUPS as $testGroup) {
- unset($yml['groups'][$testGroup]);
- }
-
- file_put_contents(self::CONFIG_YML_FILE, Yaml::dump($yml, 10));
- }
DirSetupUtil::rmdirRecursive(self::GENERATE_RESULT_DIR);
- }
- /**
- * Remove yml if created during tests and did not exist before
- */
- public static function tearDownAfterClass()
- {
- if (!self::$YML_EXISTS_FLAG) {
- unlink(self::CONFIG_YML_FILE);
- }
+ // delete config yml file from test dir
+ $fileSystem = new \Symfony\Component\Filesystem\Filesystem();
+ $fileSystem->remove(
+ self::CONFIG_YML_FILE
+ );
}
/**
diff --git a/.env.example b/etc/config/.env.example
similarity index 100%
rename from .env.example
rename to etc/config/.env.example
diff --git a/codeception.dist.yml b/etc/config/codeception.dist.yml
similarity index 72%
rename from codeception.dist.yml
rename to etc/config/codeception.dist.yml
index 25093c681..273ede0b0 100755
--- a/codeception.dist.yml
+++ b/etc/config/codeception.dist.yml
@@ -2,19 +2,19 @@
# See COPYING.txt for license details.
actor: Tester
paths:
- tests: dev/tests/functional
- log: dev/tests/functional/_output
- data: dev/tests/functional/_data
+ tests: tests
+ log: tests/_output
+ data: tests/_data
support: src/Magento/FunctionalTestingFramework
envs: etc/_envs
settings:
- bootstrap: _bootstrap.php
colors: true
memory_limit: 1024M
extensions:
enabled:
- Codeception\Extension\RunFailed
- - Yandex\Allure\Adapter\AllureAdapter
+ - Magento\FunctionalTestingFramework\Extension\TestContextExtension
+ - Magento\FunctionalTestingFramework\Allure\Adapter\MagentoAllureAdapter
config:
Yandex\Allure\Adapter\AllureAdapter:
deletePreviousResults: true
diff --git a/dev/tests/functional/MFTF.suite.dist.yml b/etc/config/functional.suite.dist.yml
similarity index 84%
rename from dev/tests/functional/MFTF.suite.dist.yml
rename to etc/config/functional.suite.dist.yml
index a54620385..bfd093e41 100644
--- a/dev/tests/functional/MFTF.suite.dist.yml
+++ b/etc/config/functional.suite.dist.yml
@@ -14,14 +14,15 @@ modules:
- \Magento\FunctionalTestingFramework\Module\MagentoWebDriver
- \Magento\FunctionalTestingFramework\Helper\Acceptance
- \Magento\FunctionalTestingFramework\Helper\MagentoFakerData
+ - \Magento\FunctionalTestingFramework\Module\MagentoSequence
- \Magento\FunctionalTestingFramework\Module\MagentoAssert
- Asserts
config:
\Magento\FunctionalTestingFramework\Module\MagentoWebDriver:
url: "%MAGENTO_BASE_URL%"
backend_name: "%MAGENTO_BACKEND_NAME%"
- browser: '%BROWSER%'
- window_size: maximize
+ browser: 'chrome'
+ window_size: 1280x1024
username: "%MAGENTO_ADMIN_USERNAME%"
password: "%MAGENTO_ADMIN_PASSWORD%"
pageload_timeout: 30
@@ -31,5 +32,5 @@ modules:
path: %SELENIUM_PATH%
capabilities:
chromeOptions:
- args: ["--start-maximized", "--disable-extensions", "--enable-automation"]
+ args: ["--incognito", "--disable-extensions", "--enable-automation"]
diff --git a/src/Magento/FunctionalTestingFramework/Config/FileResolver/Root.php b/src/Magento/FunctionalTestingFramework/Config/FileResolver/Root.php
index 93e74a82c..3b0940b28 100644
--- a/src/Magento/FunctionalTestingFramework/Config/FileResolver/Root.php
+++ b/src/Magento/FunctionalTestingFramework/Config/FileResolver/Root.php
@@ -11,7 +11,7 @@
class Root extends Module
{
- const ROOT_SUITE_DIR = "_suite";
+ const ROOT_SUITE_DIR = "tests/_suite";
/**
* Retrieve the list of configuration files with given name that relate to specified scope at the root level as well
@@ -25,7 +25,7 @@ public function get($filename, $scope)
{
// first pick up the root level test suite dir
$paths = glob(
- dirname(TESTS_BP) . DIRECTORY_SEPARATOR . self::ROOT_SUITE_DIR
+ TESTS_BP . DIRECTORY_SEPARATOR . self::ROOT_SUITE_DIR
. DIRECTORY_SEPARATOR . $filename
);
diff --git a/src/Magento/FunctionalTestingFramework/Console/BuildProjectCommand.php b/src/Magento/FunctionalTestingFramework/Console/BuildProjectCommand.php
index 6e29ac071..ea5c5795f 100644
--- a/src/Magento/FunctionalTestingFramework/Console/BuildProjectCommand.php
+++ b/src/Magento/FunctionalTestingFramework/Console/BuildProjectCommand.php
@@ -16,9 +16,12 @@
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;
use Magento\FunctionalTestingFramework\Util\Env\EnvProcessor;
+use Symfony\Component\Yaml\Yaml;
class BuildProjectCommand extends Command
{
+ const DEFAULT_YAML_INLINE_DEPTH = 10;
+
/**
* Env processor manages .env files.
*
@@ -33,9 +36,9 @@ class BuildProjectCommand extends Command
*/
protected function configure()
{
- $this->setName('build:project');
- $this->setDescription('Generate configuration files for the project. Build the Codeception project.');
- $this->envProcessor = new EnvProcessor(BP . DIRECTORY_SEPARATOR . '.env');
+ $this->setName('build:project')
+ ->setDescription('Generate configuration files for the project. Build the Codeception project.');
+ $this->envProcessor = new EnvProcessor(TESTS_BP . DIRECTORY_SEPARATOR . '.env');
$env = $this->envProcessor->getEnv();
foreach ($env as $key => $value) {
$this->addOption($key, null, InputOption::VALUE_REQUIRED, '', $value);
@@ -49,22 +52,12 @@ protected function configure()
* @param OutputInterface $output
* @return void
* @throws \Symfony\Component\Console\Exception\LogicException
+ *
+ * @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
- $fileSystem = new Filesystem();
- $fileSystem->copy(
- BP . DIRECTORY_SEPARATOR . 'codeception.dist.yml',
- BP . DIRECTORY_SEPARATOR . 'codeception.yml'
- );
- $output->writeln("codeception.yml configuration successfully applied.\n");
- $fileSystem->copy(
- BP . DIRECTORY_SEPARATOR . 'dev' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR .
- 'functional' . DIRECTORY_SEPARATOR . 'MFTF.suite.dist.yml',
- BP . DIRECTORY_SEPARATOR . 'dev' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR .
- 'functional' . DIRECTORY_SEPARATOR . 'MFTF.suite.yml'
- );
- $output->writeln("MFTF.suite.yml configuration successfully applied.\n");
+ $this->generateConfigFiles($output);
$setupEnvCommand = new SetupEnvCommand();
$commandInput = [];
@@ -78,12 +71,58 @@ protected function execute(InputInterface $input, OutputInterface $output)
$commandInput = new ArrayInput($commandInput);
$setupEnvCommand->run($commandInput, $output);
- $process = new Process('vendor/bin/codecept build');
- $process->run();
- if ($process->isSuccessful()) {
- $output->writeln("Codeception build run successfully.\n");
+
+ // TODO can we just import the codecept symfony command?
+ $codeceptBuildCommand = realpath(PROJECT_ROOT . '/vendor/bin/codecept') . ' build';
+ $process = new Process($codeceptBuildCommand);
+ $process->setWorkingDirectory(TESTS_BP);
+ $process->run(
+ function ($type, $buffer) use ($output) {
+ if ($output->isVerbose()) {
+ $output->write($buffer);
+ }
+ }
+ );
+ }
+
+ /**
+ * Generates needed codeception configuration files to the TEST_BP directory
+ *
+ * @param OutputInterface $output
+ * @return void
+ */
+ private function generateConfigFiles(OutputInterface $output)
+ {
+ $fileSystem = new Filesystem();
+ //Find travel path from codeception.yml to FW_BP
+ $relativePath = $fileSystem->makePathRelative(FW_BP, TESTS_BP);
+
+ if (!$fileSystem->exists(TESTS_BP . DIRECTORY_SEPARATOR . 'codeception.yml')) {
+ // read in the codeception.yml file
+ $configDistYml = Yaml::parse(file_get_contents(realpath(FW_BP . "/etc/config/codeception.dist.yml")));
+ $configDistYml['paths']['support'] = $relativePath . 'src/Magento/FunctionalTestingFramework';
+ $configDistYml['paths']['envs'] = $relativePath . 'etc/_envs';
+ $configYmlText = Yaml::dump($configDistYml, self::DEFAULT_YAML_INLINE_DEPTH);
+
+ // dump output to new codeception.yml file
+ file_put_contents(TESTS_BP . DIRECTORY_SEPARATOR . 'codeception.yml', $configYmlText);
+ $output->writeln("codeception.yml configuration successfully applied.");
}
- $output->writeln('The project built successfully.');
+ if ($output->isVerbose()) {
+ $output->writeln("codeception.yml applied to " . TESTS_BP . DIRECTORY_SEPARATOR . 'codeception.yml');
+ }
+
+ // copy the functional suite yml, this will only copy if there are differences between the template the destination
+ $fileSystem->copy(
+ realpath(FW_BP . '/etc/config/functional.suite.dist.yml'),
+ TESTS_BP . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'functional.suite.yml'
+ );
+ $output->writeln('functional.suite.yml configuration successfully applied.');
+
+ if ($output->isVerbose()) {
+ $output->writeln("functional.suite.yml applied to " .
+ TESTS_BP . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'functional.suite.yml');
+ }
}
}
diff --git a/src/Magento/FunctionalTestingFramework/Console/CleanProjectCommand.php b/src/Magento/FunctionalTestingFramework/Console/CleanProjectCommand.php
new file mode 100644
index 000000000..c2d388898
--- /dev/null
+++ b/src/Magento/FunctionalTestingFramework/Console/CleanProjectCommand.php
@@ -0,0 +1,92 @@
+setName('reset')
+ ->setDescription('This command will clean any configuration files from the environment (not including .env), as well as any generated artifacts.')
+ ->addOption('hard', null, InputOption::VALUE_NONE, "parameter to force reset of configuration files.");
+ }
+
+ /**
+ * Executes the current command.
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return void
+ * @throws \Symfony\Component\Console\Exception\LogicException
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $isHardReset = $input->getOption('hard');
+ $fileSystem = new Filesystem();
+ $finder = new Finder();
+ $finder->files()->name('*.php')->in(realpath(FW_BP . '/src/Magento/FunctionalTestingFramework/Group/'));
+ $filesForRemoval = [];
+
+ // include config files if user specifies a hard reset for deletion
+ if ($isHardReset) {
+ $filesForRemoval = array_merge($filesForRemoval, self::CONFIGURATION_FILES);
+ }
+
+ // include the files mftf generates during test execution in TESTS_BP for deletion
+ $filesForRemoval = array_merge($filesForRemoval, self::GENERATED_FILES);
+
+ if ($output->isVerbose()) {
+ $output->writeln('Deleting Files:');
+ }
+
+ // delete any suite based group files
+ foreach ($finder->files() as $file) {
+ if ($output->isVerbose()) {
+ $output->writeln($file->getRealPath());
+ }
+
+ $fileSystem->remove($file);
+ }
+
+ // delete files specified for removal
+ foreach ($filesForRemoval as $fileForRemoval) {
+ if ($fileSystem->exists($fileForRemoval) && $output->isVerbose()) {
+ $output->writeln($fileForRemoval);
+ }
+
+ $fileSystem->remove($fileForRemoval);
+ }
+
+ $output->writeln('mftf files removed from filesystem.');
+ }
+}
diff --git a/src/Magento/FunctionalTestingFramework/Console/GenerateSuiteCommand.php b/src/Magento/FunctionalTestingFramework/Console/GenerateSuiteCommand.php
new file mode 100644
index 000000000..d94e5fa2e
--- /dev/null
+++ b/src/Magento/FunctionalTestingFramework/Console/GenerateSuiteCommand.php
@@ -0,0 +1,56 @@
+setName('generate:suite')
+ ->setDescription('This command generates a single suite based on declaration in xml')
+ ->addArgument(
+ 'suites',
+ InputArgument::IS_ARRAY | InputArgument::REQUIRED,
+ 'argument which indicates suite names for generation (separated by space)'
+ );
+ }
+
+ /**
+ * Executes the current command.
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return void
+ * @throws \Symfony\Component\Console\Exception\LogicException
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $suites = $input->getArgument('suites');
+
+ foreach ($suites as $suite) {
+ SuiteGenerator::getInstance()->generateSuite($suite);
+ if ($output->isVerbose()) {
+ $output->writeLn("suite $suite generated");
+ }
+ }
+
+ $output->writeLn("Suites Generated");
+ }
+}
diff --git a/src/Magento/FunctionalTestingFramework/Console/GenerateTestsCommand.php b/src/Magento/FunctionalTestingFramework/Console/GenerateTestsCommand.php
new file mode 100644
index 000000000..a8d34f1c9
--- /dev/null
+++ b/src/Magento/FunctionalTestingFramework/Console/GenerateTestsCommand.php
@@ -0,0 +1,140 @@
+setName('generate:tests')
+ ->setDescription('This command generates all test files and suites based on xml declarations')
+ ->addArgument('name', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'name(s) of specific tests to generate')
+ ->addOption("config", 'c', InputOption::VALUE_REQUIRED, 'default, singleRun, or parallel', 'default')
+ ->addOption("force", 'f',InputOption::VALUE_NONE, 'force generation of tests regardless of Magento Instance Configuration')
+ ->addOption('lines', 'l', InputOption::VALUE_REQUIRED, 'Used in combination with a parallel configuration, determines desired group size', 500)
+ ->addOption('tests', 't', InputOption::VALUE_REQUIRED, 'A parameter accepting a JSON string used to determine the test configuration');
+ }
+
+ /**
+ * Executes the current command.
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return void
+ * @throws \Symfony\Component\Console\Exception\LogicException
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $tests = $input->getArgument('name');
+ $config = $input->getOption('config');
+ $json = $input->getOption('tests');
+ $force = $input->getOption('force');
+ $lines = $input->getOption('lines');
+ $verbose = $output->isVerbose();
+
+ if ($json !== null && !json_decode($json)) {
+ // stop execution if we have failed to properly parse any json passed in by the user
+ throw new TestFrameworkException("JSON could not be parsed: " . json_last_error_msg());
+ }
+
+ $testConfiguration = $this->createTestConfiguration($json, $tests, $force, $verbose);
+
+ // create our manifest file here
+ $testManifest = TestManifestFactory::makeManifest($config, $testConfiguration['suites']);
+ TestGenerator::getInstance(null, $testConfiguration['tests'])->createAllTestFiles($testManifest);
+
+ if ($config == 'parallel') {
+ /** @var ParallelTestManifest $testManifest */
+ $testManifest->createTestGroups($lines);
+ }
+
+ SuiteGenerator::getInstance()->generateAllSuites($testManifest);
+ $testManifest->generate();
+
+ print "Generate Tests Command Run" . PHP_EOL;
+ }
+
+ /**
+ * Function which builds up a configuration including test and suites for consumption of Magento generation methods.
+ *
+ * @param string $json
+ * @param array $tests
+ * @param bool $force
+ * @param bool $verbose
+ * @return array
+ */
+ private function createTestConfiguration($json, array $tests, bool $force, bool $verbose)
+ {
+ // set our application configuration so we can references the user options in our framework
+ MftfApplicationConfig::create(
+ $force,
+ MftfApplicationConfig::GENERATION_PHASE,
+ $verbose
+ );
+
+ $testConfiguration = [];
+ $testConfiguration['tests'] = $tests;
+ $testConfiguration['suites'] = [];
+
+ $testConfiguration = $this->parseTestsConfigJson($json, $testConfiguration);
+
+ // if we have references to specific tests, we resolve the test objects and pass them to the config
+ if (!empty($testConfiguration['tests'])) {
+ $testObjects = [];
+
+ foreach ($testConfiguration['tests'] as $test) {
+ $testObjects[$test] = TestObjectHandler::getInstance()->getObject($test);
+ }
+
+ $testConfiguration['tests'] = $testObjects;
+ }
+
+ return $testConfiguration;
+ }
+
+ /**
+ * Function which takes a json string of potential custom configuration and parses/validates the resulting json
+ * passed in by the user. The result is a testConfiguration array.
+ *
+ * @param string $json
+ * @param array $testConfiguration
+ * @throws TestFrameworkException
+ * @return array
+ */
+ private function parseTestsConfigJson($json, array $testConfiguration) {
+ if ($json === null) {
+ return $testConfiguration;
+ }
+
+ $jsonTestConfiguration = [];
+ $testConfigArray = json_decode($json, true);
+
+ $jsonTestConfiguration['tests'] = $testConfigArray['tests'] ?? null;;
+ $jsonTestConfiguration['suites'] = $testConfigArray['suites'] ?? null;
+ return $jsonTestConfiguration;
+ }
+}
diff --git a/src/Magento/FunctionalTestingFramework/Console/RunTestCommand.php b/src/Magento/FunctionalTestingFramework/Console/RunTestCommand.php
new file mode 100644
index 000000000..6041d0be5
--- /dev/null
+++ b/src/Magento/FunctionalTestingFramework/Console/RunTestCommand.php
@@ -0,0 +1,73 @@
+setName("run:test")
+ ->setDescription("generation and execution of test(s) defined in xml")
+ ->addArgument('name', InputArgument::REQUIRED | InputArgument::IS_ARRAY, "name of tests to generate and execute")
+ ->addOption('skip-generate', 'k', InputOption::VALUE_NONE, "skip generation and execute existing test");
+ }
+
+ /**
+ * Executes the current command.
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return void
+ * @throws \Symfony\Component\Console\Exception\LogicException
+ *
+ * @SuppressWarnings(PHPMD.UnusedLocalVariable)
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $tests = $input->getArgument('name');
+ $skipGeneration = $input->getOption('skip-generate') ?? false;
+
+ if (!$skipGeneration) {
+ $command = $this->getApplication()->find('generate:tests');
+ $args = [
+ '--tests' => json_encode([
+ 'tests' => $tests,
+ 'suites' => null
+ ])
+ ];
+
+ $command->run(new ArrayInput($args), $output);
+ }
+
+ // we only generate relevant tests here so we can execute "all tests"
+ $codeceptionCommand = realpath(PROJECT_ROOT . '/vendor/bin/codecept') . " run functional --verbose --steps";
+
+ $process = new Process($codeceptionCommand);
+ $process->setWorkingDirectory(TESTS_BP);
+ $process->run(
+ function ($type, $buffer) use ($output) {
+ $output->write($buffer);
+ }
+ );
+ }
+
+}
diff --git a/src/Magento/FunctionalTestingFramework/Console/RunTestGroupCommand.php b/src/Magento/FunctionalTestingFramework/Console/RunTestGroupCommand.php
new file mode 100644
index 000000000..c0e5d99b7
--- /dev/null
+++ b/src/Magento/FunctionalTestingFramework/Console/RunTestGroupCommand.php
@@ -0,0 +1,104 @@
+setName('run:group')
+ ->setDescription('Execute a set of tests referenced via group annotations')
+ ->addOption('skip-generate', 'k', InputOption::VALUE_NONE, "only execute a group of tests without generating from source xml")
+ ->addArgument(
+ 'groups',
+ InputArgument::IS_ARRAY | InputArgument::REQUIRED,
+ 'group names to be executed via codeception'
+ );
+ }
+
+ /**
+ * Executes the current command.
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return void
+ * @throws \Symfony\Component\Console\Exception\LogicException
+ *
+ * @SuppressWarnings(PHPMD.UnusedLocalVariable)
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $skipGeneration = $input->getOption('skip-generate') ?? false;
+ $groups = $input->getArgument('groups');
+
+ if (!$skipGeneration) {
+ $testConfiguration = $this->getGroupAndSuiteConfiguration($groups);
+ $command = $this->getApplication()->find('generate:tests');
+ $args = ['--tests' => $testConfiguration];
+
+ $command->run(new ArrayInput($args), $output);
+ }
+
+ $codeceptionCommand = realpath(PROJECT_ROOT . '/vendor/bin/codecept') . ' run functional --verbose --steps';
+
+ foreach ($groups as $group) {
+ $codeceptionCommand .= " -g {$group}";
+ }
+
+ $process = new Process($codeceptionCommand);
+ $process->setWorkingDirectory(TESTS_BP);
+ $process->run(
+ function ($type, $buffer) use ($output) {
+ $output->write($buffer);
+ }
+ );
+ }
+
+ /**
+ * Returns a json string to be used as an argument for generation of a group or suite
+ *
+ * @param array $groups
+ * @return string
+ */
+ private function getGroupAndSuiteConfiguration(array $groups)
+ {
+ $testConfiguration['tests'] = [];
+ $testConfiguration['suites'] = null;
+ $availableSuites = SuiteObjectHandler::getInstance()->getAllObjects();
+
+ foreach ($groups as $group) {
+ if (array_key_exists($group, $availableSuites)) {
+ $testConfiguration['suites'][$group] = [];
+ }
+
+ $testConfiguration['tests'] = array_merge(
+ $testConfiguration['tests'],
+ array_keys(TestObjectHandler::getInstance()->getTestsByGroup($group))
+ );
+ }
+
+ $testConfigurationJson = json_encode($testConfiguration);
+ return $testConfigurationJson;
+ }
+}
diff --git a/src/Magento/FunctionalTestingFramework/Console/SetupEnvCommand.php b/src/Magento/FunctionalTestingFramework/Console/SetupEnvCommand.php
index e0ef6053a..5b57c43d7 100644
--- a/src/Magento/FunctionalTestingFramework/Console/SetupEnvCommand.php
+++ b/src/Magento/FunctionalTestingFramework/Console/SetupEnvCommand.php
@@ -31,9 +31,9 @@ class SetupEnvCommand extends Command
*/
protected function configure()
{
- $this->setName('setup:env');
- $this->setDescription("Generate .env file.");
- $this->envProcessor = new EnvProcessor(BP . DIRECTORY_SEPARATOR . '.env');
+ $this->setName('setup:env')
+ ->setDescription("Generate .env file.");
+ $this->envProcessor = new EnvProcessor(TESTS_BP . DIRECTORY_SEPARATOR . '.env');
$env = $this->envProcessor->getEnv();
foreach ($env as $key => $value) {
$this->addOption($key, null, InputOption::VALUE_REQUIRED, '', $value);
@@ -59,6 +59,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
$userEnv[$key] = $input->getOption($key);
}
$this->envProcessor->putEnvFile($userEnv);
- $output->writeln(".env configuration successfully applied.\n");
+ $output->writeln(".env configuration successfully applied.");
}
}
diff --git a/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php b/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php
index 7ae362591..c7b31610a 100644
--- a/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php
+++ b/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php
@@ -241,7 +241,8 @@ private function generateGroupFile($suiteName, $tests, $originalSuiteName)
*/
private function appendEntriesToConfig($suiteName, $suitePath, $groupNamespace)
{
- $relativeSuitePath = substr($suitePath, strlen(dirname(dirname(TESTS_BP))) + 1);
+ $relativeSuitePath = substr($suitePath, strlen(TESTS_BP));
+ $relativeSuitePath = ltrim($relativeSuitePath, DIRECTORY_SEPARATOR);
$ymlArray = self::getYamlFileContents();
if (!array_key_exists(self::YAML_GROUPS_TAG, $ymlArray)) {
@@ -344,6 +345,6 @@ private static function getYamlFileContents()
*/
private static function getYamlConfigFilePath()
{
- return dirname(dirname(TESTS_BP)) . DIRECTORY_SEPARATOR;
+ return TESTS_BP . DIRECTORY_SEPARATOR;
}
}
diff --git a/src/Magento/FunctionalTestingFramework/Util/Env/EnvProcessor.php b/src/Magento/FunctionalTestingFramework/Util/Env/EnvProcessor.php
index 7129ff091..53871a098 100644
--- a/src/Magento/FunctionalTestingFramework/Util/Env/EnvProcessor.php
+++ b/src/Magento/FunctionalTestingFramework/Util/Env/EnvProcessor.php
@@ -36,6 +36,13 @@ class EnvProcessor
*/
private $env = [];
+ /**
+ * Boolean indicating existence of env file
+ *
+ * @var bool
+ */
+ private $envExists;
+
/**
* EnvProcessor constructor.
* @param string $envFile
@@ -44,33 +51,50 @@ public function __construct(
string $envFile = ''
) {
$this->envFile = $envFile;
- $this->envExampleFile = $envFile . '.example';
+ $this->envExists = file_exists($envFile);
+ $this->envExampleFile = realpath(FW_BP . "/etc/config/.env.example");
}
/**
- * Serves for parsing '.env.example' file into associative array.
+ * Serves for parsing '.env' file into associative array.
*
* @return array
*/
- public function parseEnvFile(): array
+ private function parseEnvFile(): array
{
- $envLines = file(
+ $envExampleFile = file(
$this->envExampleFile,
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES
);
- $env = [];
- foreach ($envLines as $line) {
+
+ $envContents = [];
+ if ($this->envExists) {
+ $envFile = file(
+ $this->envFile,
+ FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES
+ );
+
+ $envContents = $this->parseEnvFileLines($envFile);
+ }
+
+ return array_diff_key($this->parseEnvFileLines($envExampleFile), $envContents);
+ }
+
+ private function parseEnvFileLines(array $file): array
+ {
+ $fileArray = [];
+ foreach ($file as $line) {
// do not use commented out lines
if (strpos($line, '#') !== 0) {
list($key, $value) = explode('=', $line);
- $env[$key] = $value;
+ $fileArray[$key] = $value;
}
}
- return $env;
+ return $fileArray;
}
/**
- * Serves for putting array with environment variables into .env file.
+ * Serves for putting array with environment variables into .env file or appending new variables we introduce
*
* @param array $config
* @return void
@@ -81,7 +105,12 @@ public function putEnvFile(array $config = [])
foreach ($config as $key => $value) {
$envData .= $key . '=' . $value . PHP_EOL;
}
- file_put_contents($this->envFile, $envData);
+
+ if ($this->envExists) {
+ file_put_contents($this->envFile, $envData, FILE_APPEND);
+ } else {
+ file_put_contents($this->envFile, $envData);
+ }
}
/**
diff --git a/src/Magento/FunctionalTestingFramework/Util/Manifest/BaseTestManifest.php b/src/Magento/FunctionalTestingFramework/Util/Manifest/BaseTestManifest.php
index 3c3eb6de9..e5ce1ee50 100644
--- a/src/Magento/FunctionalTestingFramework/Util/Manifest/BaseTestManifest.php
+++ b/src/Magento/FunctionalTestingFramework/Util/Manifest/BaseTestManifest.php
@@ -43,7 +43,8 @@ abstract class BaseTestManifest
public function __construct($path, $runConfig, $suiteConfiguration)
{
$this->runTypeConfig = $runConfig;
- $this->relativeDirPath = substr($path, strlen(dirname(dirname(TESTS_BP))) + 1);
+ $relativeDirPath = substr($path, strlen(TESTS_BP));
+ $this->relativeDirPath = ltrim($relativeDirPath, DIRECTORY_SEPARATOR);
$this->suiteConfiguration = $suiteConfiguration;
}
diff --git a/src/Magento/FunctionalTestingFramework/Util/ModuleResolver.php b/src/Magento/FunctionalTestingFramework/Util/ModuleResolver.php
index 43b472b4d..275f8fc57 100644
--- a/src/Magento/FunctionalTestingFramework/Util/ModuleResolver.php
+++ b/src/Magento/FunctionalTestingFramework/Util/ModuleResolver.php
@@ -229,6 +229,7 @@ private function aggregateTestModulePaths()
// Define the Module paths from default TESTS_MODULE_PATH
$modulePath = defined('TESTS_MODULE_PATH') ? TESTS_MODULE_PATH : TESTS_BP;
+ $modulePath = rtrim($modulePath, DIRECTORY_SEPARATOR);
// Define the Module paths from vendor modules
$vendorCodePath = PROJECT_ROOT
diff --git a/src/Magento/FunctionalTestingFramework/_bootstrap.php b/src/Magento/FunctionalTestingFramework/_bootstrap.php
new file mode 100644
index 000000000..3dd871adc
--- /dev/null
+++ b/src/Magento/FunctionalTestingFramework/_bootstrap.php
@@ -0,0 +1,63 @@
+load();
+
+ if (array_key_exists('TESTS_MODULE_PATH', $_ENV) xor array_key_exists('TESTS_BP', $_ENV)) {
+ throw new Exception(
+ 'You must define both parameters TESTS_BP and TESTS_MODULE_PATH or neither parameter'
+ );
+ }
+
+ foreach ($_ENV as $key => $var) {
+ defined($key) || define($key, $var);
+ }
+
+ defined('MAGENTO_CLI_COMMAND_PATH') || define(
+ 'MAGENTO_CLI_COMMAND_PATH',
+ 'dev/tests/acceptance/utils/command.php'
+ );
+ $env->setEnvironmentVariable('MAGENTO_CLI_COMMAND_PATH', MAGENTO_CLI_COMMAND_PATH);
+
+ defined('MAGENTO_CLI_COMMAND_PARAMETER') || define('MAGENTO_CLI_COMMAND_PARAMETER', 'command');
+ $env->setEnvironmentVariable('MAGENTO_CLI_COMMAND_PARAMETER', MAGENTO_CLI_COMMAND_PARAMETER);
+}
+
+// TODO REMOVE THIS CODE ONCE WE HAVE STOPPED SUPPORTING dev/tests/acceptance PATH
+// define TEST_PATH and TEST_MODULE_PATH
+defined('TESTS_BP') || define('TESTS_BP', realpath(MAGENTO_BP . DIRECTORY_SEPARATOR . 'dev/tests/acceptance/'));
+
+$RELATIVE_TESTS_MODULE_PATH = '/tests/functional/Magento/FunctionalTest';
+defined('TESTS_MODULE_PATH') || define(
+ 'TESTS_MODULE_PATH',
+ realpath(TESTS_BP . $RELATIVE_TESTS_MODULE_PATH)
+);
+
+// add the debug flag here
+$debugMode = $_ENV['MFTF_DEBUG'] ?? false;
+if (!(bool)$debugMode && extension_loaded('xdebug')) {
+ xdebug_disable();
+}