setDefinition([
            new InputArgument('suite', InputArgument::REQUIRED, 'suite to be executed'),
            new InputOption('colors', '', InputOption::VALUE_NONE, 'Use colors in output'),
        ]);
        parent::configure();
    }
    public function getDescription()
    {
        return 'Launches interactive test console';
    }
    public function execute(InputInterface $input, OutputInterface $output)
    {
        $suiteName = $input->getArgument('suite');
        $this->output = $output;
        $config = Configuration::config();
        $settings = Configuration::suiteSettings($suiteName, $config);
        $options = $input->getOptions();
        $options['debug'] = true;
        $options['silent'] = true;
        $options['interactive'] = false;
        $options['colors'] = true;
        Debug::setOutput(new Output($options));
        $this->codecept = new Codecept($options);
        $dispatcher = $this->codecept->getDispatcher();
        $suiteManager = new SuiteManager($dispatcher, $suiteName, $settings);
        $suiteManager->initialize();
        $this->suite = $suiteManager->getSuite();
        $moduleContainer = $suiteManager->getModuleContainer();
        $this->actions = array_keys($moduleContainer->getActions());
        $this->test = new Cept(null, null);
        $this->test->getMetadata()->setServices([
           'dispatcher' => $dispatcher,
           'modules' =>  $moduleContainer
        ]);
        $scenario = new Scenario($this->test);
        if (!$settings['actor']) {
            throw new ConfigurationException("Interactive shell can't be started without an actor");
        }
        if (isset($config["namespace"])) {
            $settings['actor'] = $config["namespace"] .'\\' . $settings['actor'];
        }
        $actor = $settings['actor'];
        $I = new $actor($scenario);
        $this->listenToSignals();
        $output->writeln("Interactive console started for suite $suiteName");
        $output->writeln("Try Codeception commands without writing a test");
        $output->writeln("type 'exit' to leave console");
        $output->writeln("type 'actions' to see all available actions for this suite");
        $suiteEvent = new SuiteEvent($this->suite, $this->codecept->getResult(), $settings);
        $dispatcher->dispatch(Events::SUITE_BEFORE, $suiteEvent);
        $dispatcher->dispatch(Events::TEST_PARSED, new TestEvent($this->test));
        $dispatcher->dispatch(Events::TEST_BEFORE, new TestEvent($this->test));
        $output->writeln("\n\n\$I = new {$settings['actor']}(\$scenario);");
        $this->executeCommands($input, $output, $I, $settings['bootstrap']);
        $dispatcher->dispatch(Events::TEST_AFTER, new TestEvent($this->test));
        $dispatcher->dispatch(Events::SUITE_AFTER, new SuiteEvent($this->suite));
        $output->writeln("Bye-bye!");
    }
    protected function executeCommands(InputInterface $input, OutputInterface $output, $I, $bootstrap)
    {
        $dialog = new QuestionHelper();
        if (file_exists($bootstrap)) {
            require $bootstrap;
        }
        do {
            $question = new Question("\$I->");
            $question->setAutocompleterValues($this->actions);
            $command = $dialog->ask($input, $output, $question);
            if ($command == 'actions') {
                $output->writeln("" . implode(' ', $this->actions));
                continue;
            }
            if ($command == 'exit') {
                return;
            }
            if ($command == '') {
                continue;
            }
            try {
                $value = eval("return \$I->$command;");
                if ($value && !is_object($value)) {
                    codecept_debug($value);
                }
            } catch (\PHPUnit\Framework\AssertionFailedError $fail) {
                $output->writeln("fail " . $fail->getMessage());
            } catch (\Exception $e) {
                $output->writeln("error " . $e->getMessage());
            }
        } while (true);
    }
    protected function listenToSignals()
    {
        if (function_exists('pcntl_signal')) {
            declare (ticks = 1);
            pcntl_signal(SIGINT, SIG_IGN);
            pcntl_signal(SIGTERM, SIG_IGN);
        }
    }
}