--- /dev/null
+<?php
+namespace Robo\Task\Testing;
+
+use Robo\Contract\CommandInterface;
+use Robo\Contract\PrintedInterface;
+use Robo\Task\BaseTask;
+
+/**
+ * Executes Behat tests
+ *
+ * ``` php
+ * <?php
+ * $this->taskBehat()
+ * ->format('pretty')
+ * ->noInteraction()
+ * ->run();
+ * ?>
+ * ```
+ *
+ */
+class Behat extends BaseTask implements CommandInterface, PrintedInterface
+{
+ use \Robo\Common\ExecOneCommand;
+
+ /**
+ * @var string
+ */
+ protected $command;
+
+ /**
+ * @var string[] $formaters available formaters for format option
+ */
+ protected $formaters = ['progress', 'pretty', 'junit'];
+
+ /**
+ * @var string[] $verbose_levels available verbose levels
+ */
+ protected $verbose_levels = ['v', 'vv'];
+
+ /**
+ * Behat constructor.
+ *
+ * @param null|string $pathToBehat
+ *
+ * @throws \Robo\Exception\TaskException
+ */
+ public function __construct($pathToBehat = null)
+ {
+ $this->command = $pathToBehat;
+ if (!$this->command) {
+ $this->command = $this->findExecutable('behat');
+ }
+ if (!$this->command) {
+ throw new \Robo\Exception\TaskException(__CLASS__, "Neither composer nor phar installation of Behat found");
+ }
+ }
+
+ /**
+ * @return $this
+ */
+ public function stopOnFail()
+ {
+ $this->option('stop-on-failure');
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function noInteraction()
+ {
+ $this->option('no-interaction');
+ return $this;
+ }
+
+ /**
+ * @param $config_file
+ *
+ * @return $this
+ */
+ public function config($config_file)
+ {
+ $this->option('config', $config_file);
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function colors()
+ {
+ $this->option('colors');
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function noColors()
+ {
+ $this->option('no-colors');
+ return $this;
+ }
+
+ /**
+ * @param string $suite
+ *
+ * @return $this
+ */
+ public function suite($suite)
+ {
+ $this->option('suite', $suite);
+ return $this;
+ }
+
+ /**
+ * @param string $level
+ *
+ * @return $this
+ */
+ public function verbose($level = 'v')
+ {
+ if (!in_array($level, $this->verbose_levels)) {
+ throw new \InvalidArgumentException('expected ' . implode(',', $this->verbose_levels));
+ }
+ $this->option('-' . $level);
+ return $this;
+ }
+
+ /**
+ * @param string $formater
+ *
+ * @return $this
+ */
+ public function format($formater)
+ {
+ if (!in_array($formater, $this->formaters)) {
+ throw new \InvalidArgumentException('expected ' . implode(',', $this->formaters));
+ }
+ $this->option('format', $formater);
+ return $this;
+ }
+
+ /**
+ * Returns command that can be executed.
+ * This method is used to pass generated command from one task to another.
+ *
+ * @return string
+ */
+ public function getCommand()
+ {
+ return $this->command . $this->arguments;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ $this->printTaskInfo('Running behat {arguments}', ['arguments' => $this->arguments]);
+ return $this->executeCommand($this->getCommand());
+ }
+}