ÿØÿà JFIF    ÿÛ „  ( %!1"%)+...383-7(-.+  -%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ     ÿÄ @    !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ    ÿÄ '   1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ϗ -3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéߦ$$½—šÙÜCC¯¶è8β–Åkèwx LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2޿د­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÁ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’שT ] ªb—ÊîKC^×M“xùäñz¬zJ× {4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi [0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú Ò˜Æ}2VE•Ѐp¡Ô3Úº …h³^LJºçì¥Ánó|˜ÖˆÎˆ+« ¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<̉Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈ Àá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ ƒÜÒ? :õdsÀ –3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LǐÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl Í›G¹ÀPá¼Nc¡šÒ…ÙWͳœ±vÊáЄ×9‹P‰cEØ‘™›µŸP<×g1 º©Ø¬wiÁ^l5× I/';Ë+´Z‡ÓÄFÕp[Èð’ HÄ ó 9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ QãñQtIeórVB,ÏÂf‹4#Μc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ  ÷jsςҒKÈcø(é›;k(’#ôŒQ ™C> õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~Ȧ—’-$fe«"FâUˆÊwµPÏu w+"åÉó¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ɏdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt ·K¢ÅÅ·¥RÄÊÉbKn N­R2g$VµÕó Qr#–ÓZUÏð0ÎtÙÀœz ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Δâ‘ËØ´IˆÓ°Ë‰ÞM3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z à¾] üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.ž„æ“I[ ª+·zÐÒÚ,½Ð»¶€C›7jk$๖€Ž¾ÅÙpp¶ÍþéΤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ćf× æ¢ƱqWı[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGށ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ ƈæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„ g01¬„åEM蛇Ã\6µE›‘fÙO k÷CºnÓ1`iîÒ² áÂ!ÑLÄÿ ³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#» Ç\……ßïIœÉ$¸ÎñÍ®ÔHÇ Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡ —JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ 5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*禌Éù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnݳvðÖKE¼‚ »mà ÷f®:Ë ™–4rð¡4` ܹçž~‹C=œ…¾Ïj|VDtK.ƒ"9 Ï ­–éXá³6WÒïIL-Ї Ç MoodleListFormatter.php000064400000007644152267554140011242 0ustar00. namespace Moodle\BehatExtension\Output\Formatter; use Behat\Behat\EventDispatcher\Event\AfterOutlineTested; use Behat\Behat\EventDispatcher\Event\AfterScenarioTested; use Behat\Testwork\Output\Formatter; use Behat\Testwork\Output\Printer\OutputPrinter; // phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod /** * Feature step counter for distributing features between parallel runs. * * Use it with --dry-run (and any other selectors combination) to * get the results quickly. * * @package core * @copyright 2015 onwards Rajesh Taneja * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class MoodleListFormatter implements Formatter { /** @var OutputPrinter */ private $printer; /** @var array */ private $parameters; /** @var string */ private $name; /** @var string */ private $description; /** * Initializes formatter. * * @param string $name * @param string $description * @param array $parameters * @param OutputPrinter $printer */ public function __construct($name, $description, array $parameters, OutputPrinter $printer) { $this->name = $name; $this->description = $description; $this->parameters = $parameters; $this->printer = $printer; } /** * Returns an array of event names this subscriber wants to listen to. * * @return array The event names to listen to */ public static function getSubscribedEvents() { return [ 'tester.scenario_tested.after' => 'afterScenario', 'tester.outline_tested.after' => 'afterOutlineExample', ]; } /** * Returns formatter name. * * @return string */ public function getName() { return $this->name; } /** * Returns formatter description. * * @return string */ public function getDescription() { return $this->description; } /** * Returns formatter output printer. * * @return OutputPrinter */ public function getOutputPrinter() { return $this->printer; } /** * Sets formatter parameter. * * @param string $name * @param mixed $value */ public function setParameter($name, $value) { $this->parameters[$name] = $value; } /** * Returns parameter name. * * @param string $name * * @return mixed */ public function getParameter($name) { return isset($this->parameters[$name]) ? $this->parameters[$name] : null; } /** * Listens to "scenario.after" event. * * @param AfterScenarioTested $event */ public function afterScenario(AfterScenarioTested $event) { $scenario = $event->getScenario(); $this->printer->writeln($event->getFeature()->getFile() . ':' . $scenario->getLine()); } /** * Listens to "outline.example.after" event. * * @param AfterOutlineTested $event */ public function afterOutlineExample(AfterOutlineTested $event) { $outline = $event->getOutline(); $line = $outline->getLine(); $this->printer->writeln($event->getFeature()->getFile() . ':' . $line); } } MoodleProgressFormatterFactory.php000064400000020702152267554140013451 0ustar00. namespace Moodle\BehatExtension\Output\Formatter; use Behat\Testwork\Exception\ServiceContainer\ExceptionExtension; use Behat\Testwork\Output\ServiceContainer\Formatter\FormatterFactory; use Behat\Testwork\Output\ServiceContainer\OutputExtension; use Behat\Testwork\ServiceContainer\ServiceProcessor; use Behat\Testwork\Translator\ServiceContainer\TranslatorExtension; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; // phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod /** * Moodle behat context class resolver. * * @package core * @copyright 2016 Rajesh Taneja * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class MoodleProgressFormatterFactory implements FormatterFactory { /** @var ServiceProcessor */ private $processor; /** @var string moodle progress ID */ const ROOT_LISTENER_ID_MOODLE = 'output.node.listener.moodleprogress'; /** @var string moodle printer ID */ const RESULT_TO_STRING_CONVERTER_ID_MOODLE = 'output.node.printer.result_to_string'; /** @var string Available extension points */ const ROOT_LISTENER_WRAPPER_TAG_MOODLE = 'output.node.listener.moodleprogress.wrapper'; /** * Initializes extension. * * @param null|ServiceProcessor $processor */ public function __construct(?ServiceProcessor $processor = null) { $this->processor = $processor ? : new ServiceProcessor(); } /** * Builds formatter configuration. * * @param ContainerBuilder $container */ public function buildFormatter(ContainerBuilder $container) { $this->loadRootNodeListener($container); $this->loadCorePrinters($container); $this->loadPrinterHelpers($container); $this->loadFormatter($container); } /** * Processes formatter configuration. * * @param ContainerBuilder $container */ public function processFormatter(ContainerBuilder $container) { $this->processListenerWrappers($container); } /** * Loads progress formatter node event listener. * * @param ContainerBuilder $container */ protected function loadRootNodeListener(ContainerBuilder $container) { $definition = new Definition('Behat\Behat\Output\Node\EventListener\AST\StepListener', [ new Reference('output.node.printer.moodleprogress.step') ]); $container->setDefinition(self::ROOT_LISTENER_ID_MOODLE, $definition); } /** * Loads formatter itself. * * @param ContainerBuilder $container */ protected function loadFormatter(ContainerBuilder $container) { $definition = new Definition('Behat\Behat\Output\Statistics\TotalStatistics'); $container->setDefinition('output.moodleprogress.statistics', $definition); $moodleconfig = $container->getParameter('behat.moodle.parameters'); $definition = new Definition( 'Moodle\BehatExtension\Output\Printer\MoodleProgressPrinter', [$moodleconfig['moodledirroot']] ); $container->setDefinition('moodle.output.node.printer.moodleprogress.printer', $definition); $definition = new Definition('Behat\Testwork\Output\NodeEventListeningFormatter', [ 'moodle_progress', 'Prints information about then run followed by one character per step.', [ 'timer' => true ], $this->createOutputPrinterDefinition(), new Definition('Behat\Testwork\Output\Node\EventListener\ChainEventListener', [ [ new Reference(self::ROOT_LISTENER_ID_MOODLE), new Definition('Behat\Behat\Output\Node\EventListener\Statistics\StatisticsListener', [ new Reference('output.moodleprogress.statistics'), new Reference('output.node.printer.moodleprogress.statistics') ]), new Definition('Behat\Behat\Output\Node\EventListener\Statistics\ScenarioStatsListener', [ new Reference('output.moodleprogress.statistics') ]), new Definition('Behat\Behat\Output\Node\EventListener\Statistics\StepStatsListener', [ new Reference('output.moodleprogress.statistics'), new Reference(ExceptionExtension::PRESENTER_ID) ]), new Definition('Behat\Behat\Output\Node\EventListener\Statistics\HookStatsListener', [ new Reference('output.moodleprogress.statistics'), new Reference(ExceptionExtension::PRESENTER_ID) ]), new Definition('Behat\Behat\Output\Node\EventListener\AST\SuiteListener', [ new Reference('moodle.output.node.printer.moodleprogress.printer') ]) ] ]) ]); $definition->addTag(OutputExtension::FORMATTER_TAG, ['priority' => 1]); $container->setDefinition(OutputExtension::FORMATTER_TAG . '.moodleprogress', $definition); } /** * Loads printer helpers. * * @param ContainerBuilder $container */ protected function loadPrinterHelpers(ContainerBuilder $container) { $definition = new Definition('Behat\Behat\Output\Node\Printer\Helper\ResultToStringConverter'); $container->setDefinition(self::RESULT_TO_STRING_CONVERTER_ID_MOODLE, $definition); } /** * Loads feature, scenario and step printers. * * @param ContainerBuilder $container */ protected function loadCorePrinters(ContainerBuilder $container) { $definition = new Definition('Behat\Behat\Output\Node\Printer\CounterPrinter', [ new Reference(self::RESULT_TO_STRING_CONVERTER_ID_MOODLE), new Reference(TranslatorExtension::TRANSLATOR_ID), ]); $container->setDefinition('output.node.moodle.printer.counter', $definition); $definition = new Definition('Behat\Behat\Output\Node\Printer\ListPrinter', [ new Reference(self::RESULT_TO_STRING_CONVERTER_ID_MOODLE), new Reference(ExceptionExtension::PRESENTER_ID), new Reference(TranslatorExtension::TRANSLATOR_ID), '%paths.base%' ]); $container->setDefinition('output.node.moodle.printer.list', $definition); $definition = new Definition('Behat\Behat\Output\Node\Printer\Progress\ProgressStepPrinter', [ new Reference(self::RESULT_TO_STRING_CONVERTER_ID_MOODLE) ]); $container->setDefinition('output.node.printer.moodleprogress.step', $definition); $definition = new Definition('Behat\Behat\Output\Node\Printer\Progress\ProgressStatisticsPrinter', [ new Reference('output.node.moodle.printer.counter'), new Reference('output.node.moodle.printer.list') ]); $container->setDefinition('output.node.printer.moodleprogress.statistics', $definition); } /** * Creates output printer definition. * * @return Definition */ protected function createOutputPrinterDefinition() { return new Definition('Behat\Testwork\Output\Printer\StreamOutputPrinter', [ new Definition('Behat\Behat\Output\Printer\ConsoleOutputFactory'), ]); } /** * Processes all registered pretty formatter node listener wrappers. * * @param ContainerBuilder $container */ protected function processListenerWrappers(ContainerBuilder $container) { $this->processor->processWrapperServices( $container, self::ROOT_LISTENER_ID_MOODLE, self::ROOT_LISTENER_WRAPPER_TAG_MOODLE ); } } MoodleScreenshotFormatter.php000064400000022537152267554140012442 0ustar00. namespace Moodle\BehatExtension\Output\Formatter; use Behat\Behat\EventDispatcher\Event\AfterStepTested; use Behat\Behat\EventDispatcher\Event\BeforeScenarioTested; use Behat\Behat\EventDispatcher\Event\BeforeStepTested; use Behat\Testwork\Output\Formatter; use Behat\Testwork\Output\Printer\OutputPrinter; // phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod /** * Feature step counter for distributing features between parallel runs. * * Use it with --dry-run (and any other selectors combination) to * get the results quickly. * * @package core * @copyright 2016 onwards Rajesh Taneja * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class MoodleScreenshotFormatter implements Formatter { /** @var OutputPrinter */ private $printer; /** @var array */ private $parameters; /** @var string */ private $name; /** @var string */ private $description; /** @var int The scenario count */ protected static $currentscenariocount = 0; /** @var int The step count within the current scenario */ protected static $currentscenariostepcount = 0; /** * If we are saving any kind of dump on failure we should use the same parent dir during a run. * * @var The parent dir name */ protected static $faildumpdirname = false; /** * Initializes formatter. * * @param string $name * @param string $description * @param array $parameters * @param OutputPrinter $printer */ public function __construct($name, $description, array $parameters, OutputPrinter $printer) { $this->name = $name; $this->description = $description; $this->parameters = $parameters; $this->printer = $printer; } /** * Returns an array of event names this subscriber wants to listen to. * * @return array The event names to listen to */ public static function getSubscribedEvents() { return [ 'tester.scenario_tested.before' => 'beforeScenario', 'tester.step_tested.before' => 'beforeStep', 'tester.step_tested.after' => 'afterStep', ]; } /** * Returns formatter name. * * @return string */ public function getName() { return $this->name; } /** * Returns formatter description. * * @return string */ public function getDescription() { return $this->description; } /** * Returns formatter output printer. * * @return OutputPrinter */ public function getOutputPrinter() { return $this->printer; } /** * Sets formatter parameter. * * @param string $name * @param mixed $value */ public function setParameter($name, $value) { $this->parameters[$name] = $value; } /** * Returns parameter name. * * @param string $name * @return mixed */ public function getParameter($name) { return isset($this->parameters[$name]) ? $this->parameters[$name] : null; } /** * Reset currentscenariostepcount * * @param BeforeScenarioTested $event */ public function beforeScenario(BeforeScenarioTested $event) { self::$currentscenariostepcount = 0; self::$currentscenariocount++; } /** * Increment currentscenariostepcount * * @param BeforeStepTested $event */ public function beforeStep(BeforeStepTested $event) { self::$currentscenariostepcount++; } /** * Take screenshot after step is executed. Behat\Behat\Event\html * * @param AfterStepTested $event */ public function afterStep(AfterStepTested $event) { $behathookcontext = $event->getEnvironment()->getContext('behat_hooks'); $formats = $this->getParameter('formats'); $formats = explode(',', $formats); // Take screenshot. if (in_array('image', $formats)) { $this->take_screenshot($event, $behathookcontext); } // Save html content. if (in_array('html', $formats)) { $this->take_contentdump($event, $behathookcontext); } } /** * Return screenshot directory where all screenshots will be saved. * * @return string */ protected function get_run_screenshot_dir() { global $CFG; if (self::$faildumpdirname) { return self::$faildumpdirname; } // If output_path is set then use output_path else use faildump_path. if ($this->getOutputPrinter()->getOutputPath()) { $screenshotpath = $this->getOutputPrinter()->getOutputPath(); } else if ($CFG->behat_faildump_path) { $screenshotpath = $CFG->behat_faildump_path; } else { // It should never reach here. throw new FormatterException('You should specify --out "SOME/PATH" for moodle_screenshot format'); } if ($this->getParameter('dir_permissions')) { $dirpermissions = $this->getParameter('dir_permissions'); } else { $dirpermissions = 0777; } // All the screenshot dumps should be in the same parent dir. self::$faildumpdirname = $screenshotpath . DIRECTORY_SEPARATOR . date('Ymd_His'); if (!is_dir(self::$faildumpdirname) && !mkdir(self::$faildumpdirname, $dirpermissions, true)) { // It shouldn't, we already checked that the directory is writable. throw new FormatterException(sprintf( 'No directories can be created inside %s, check the directory permissions.', $screenshotpath )); } return self::$faildumpdirname; } /** * Take screenshot when a step fails. * * @throws Exception * @param AfterStepTested $event * @param Context $context */ protected function take_screenshot(AfterStepTested $event, $context) { // BrowserKit can't save screenshots. if ($context->getMink()->isSessionStarted($context->getMink()->getDefaultSessionName())) { if (get_class($context->getMink()->getSession()->getDriver()) === 'Behat\Mink\Driver\BrowserKitDriver') { return false; } list ($dir, $filename) = $this->get_faildump_filename($event, 'png'); $context->saveScreenshot($filename, $dir); } } /** * Take a dump of the page content when a step fails. * * @throws Exception * @param AfterStepTested $event * @param \Behat\Context\Context\Context $context */ protected function take_contentdump(AfterStepTested $event, $context) { list ($dir, $filename) = $this->get_faildump_filename($event, 'html'); $fh = fopen($dir . DIRECTORY_SEPARATOR . $filename, 'w'); fwrite($fh, $context->getMink()->getSession()->getPage()->getContent()); fclose($fh); } /** * Determine the full pathname to store a failure-related dump. * * This is used for content such as the DOM, and screenshots. * * @param AfterStepTested $event * @param String $filetype The file suffix to use. Limited to 4 chars. */ protected function get_faildump_filename(AfterStepTested $event, $filetype) { // Make a directory for the scenario. $featurename = $event->getFeature()->getTitle(); $featurename = preg_replace('/([^a-zA-Z0-9\_]+)/', '-', $featurename); if ($this->getParameter('dir_permissions')) { $dirpermissions = $this->getParameter('dir_permissions'); } else { $dirpermissions = 0777; } $dir = $this->get_run_screenshot_dir(); // We want a i-am-the-scenario-title format. $dir = $dir . DIRECTORY_SEPARATOR . self::$currentscenariocount . '-' . $featurename; if (!is_dir($dir) && !mkdir($dir, $dirpermissions, true)) { // We already checked that the directory is writable. This should not fail. throw new FormatterException(sprintf( 'No directories can be created inside %s, check the directory permissions.', $dir )); } // The failed step text. // We want a stepno-i-am-the-failed-step.$filetype format. $filename = $event->getStep()->getText(); $filename = preg_replace('/([^a-zA-Z0-9\_]+)/', '-', $filename); $filename = self::$currentscenariostepcount . '-' . $filename; // File name limited to 255 characters. Leaving 4 chars for the file // extension as we allow .png for images and .html for DOM contents. $filename = substr($filename, 0, 250) . '.' . $filetype; return [$dir, $filename]; } } MoodleStepcountFormatter.php000064400000010161152267554140012277 0ustar00. namespace Moodle\BehatExtension\Output\Formatter; use Behat\Behat\EventDispatcher\Event\AfterFeatureTested; use Behat\Behat\EventDispatcher\Event\AfterStepTested; use Behat\Behat\EventDispatcher\Event\BeforeFeatureTested; use Behat\Testwork\Output\Formatter; use Behat\Testwork\Output\Printer\OutputPrinter; // phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod /** * Feature step counter for distributing features between parallel runs. * * Use it with --dry-run (and any other selectors combination) to * get the results quickly. * * @package core * @copyright 2016 onwards Rajesh Taneja * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class MoodleStepcountFormatter implements Formatter { /** @var int Number of steps executed in feature file. */ private static $stepcount = 0; /** @var OutputPrinter */ private $printer; /** @var array */ private $parameters; /** @var string */ private $name; /** @var string */ private $description; /** * Initializes formatter. * * @param string $name * @param string $description * @param array $parameters * @param OutputPrinter $printer */ public function __construct($name, $description, array $parameters, OutputPrinter $printer) { $this->name = $name; $this->description = $description; $this->parameters = $parameters; $this->printer = $printer; } /** * Returns an array of event names this subscriber wants to listen to. * * @return array The event names to listen to */ public static function getSubscribedEvents() { return [ 'tester.feature_tested.before' => 'beforeFeature', 'tester.feature_tested.after' => 'afterFeature', 'tester.step_tested.after' => 'afterStep', ]; } /** * Returns formatter name. * * @return string */ public function getName() { return $this->name; } /** * Returns formatter description. * * @return string */ public function getDescription() { return $this->description; } /** * Returns formatter output printer. * * @return OutputPrinter */ public function getOutputPrinter() { return $this->printer; } /** * Sets formatter parameter. * * @param string $name * @param mixed $value */ public function setParameter($name, $value) { $this->parameters[$name] = $value; } /** * Returns parameter name. * * @param string $name * @return mixed */ public function getParameter($name) { return isset($this->parameters[$name]) ? $this->parameters[$name] : null; } /** * Listens to "feature.before" event. * * @param BeforeFeatureTested $event */ public function beforeFeature(BeforeFeatureTested $event) { self::$stepcount = 0; } /** * Listens to "feature.after" event. * * @param AfterFeatureTested $event */ public function afterFeature(AfterFeatureTested $event) { $this->printer->writeln($event->getFeature()->getFile() . '::' . self::$stepcount); } /** * Listens to "step.after" event. * * @param AfterStepTested $event */ public function afterStep(AfterStepTested $event) { self::$stepcount++; } }