HumHub Documentation (unofficial)

Recorder extends Extension
in package

Saves a screenshot of each step in acceptance tests and shows them as a slideshow on one HTML page (here's an [example](https://codeception.com/images/recorder.gif)) Activated only for suites with WebDriver module enabled.

The screenshots are saved to tests/_output/record_* directories, open index.html to see them as a slideshow.

Installation

Add this to the list of enabled extensions in codeception.yml or acceptance.suite.yml:

extensions:
    enabled:
        - Codeception\Extension\Recorder

Configuration

  • delete_successful (default: true) - delete screenshots for successfully passed tests (i.e. log only failed and errored tests).
  • module (default: WebDriver) - which module for screenshots to use. Set AngularJS if you want to use it with AngularJS module. Generally, the module should implement Codeception\Lib\Interfaces\ScreenshotSaver interface.
  • ignore_steps (default: []) - array of step names that should not be recorded (given the step passed), * wildcards supported. Meta steps can also be ignored.
  • success_color (default: success) - bootstrap values to be used for color representation for passed tests
  • failure_color (default: danger) - bootstrap values to be used for color representation for failed tests
  • error_color (default: dark) - bootstrap values to be used for color representation for scenarios where there's an issue occurred while generating a recording
  • delete_orphaned (default: false) - delete recording folders created via previous runs
  • include_microseconds (default: false) - enable microsecond precision for recorded step time details

Examples:

extensions:
    enabled:
        - Codeception\Extension\Recorder:
            module: AngularJS # enable for Angular
            delete_successful: false # keep screenshots of successful tests
            ignore_steps: [have, grab*]

Skipping recording of steps with annotations

It is also possible to skip recording of steps for specified tests by using the @skipRecording annotation.

/**
* @skipRecording login
* @skipRecording amOnUrl
*\/
public function testLogin(AcceptanceTester $I)
{
    $I->login();
    $I->amOnUrl('https://codeception.com');
}

Table of Contents

Properties

$events  : array<string|int, mixed>
$ansi  : bool
$colors  : bool
$config  : array<string|int, mixed>
$dir  : string
$errorMessages  : array<string|int, mixed>
$globalConfig  : mixed
$indexTemplate  : string
$indicatorTemplate  : string
$options  : mixed
$output  : mixed
$recordedTests  : array<string|int, mixed>
$seed  : string
$seeds  : array<string|int, mixed>
$skipRecording  : array<string|int, mixed>
$slides  : array<string|int, mixed>
$slidesTemplate  : string
$stepNum  : int
$template  : string
$timeStamps  : array<string|int, mixed>
$webDriverModule  : WebDriver
$dateFormat  : string
$modules  : mixed

Methods

__construct()  : mixed
_initialize()  : mixed
You can do all preparations here. No need to override constructor.
_reconfigure()  : mixed
Pass config variables that should be injected into global config.
afterStep()  : mixed
afterSuite()  : mixed
before()  : mixed
beforeSuite()  : mixed
cleanup()  : mixed
getCurrentModuleNames()  : mixed
getDataDir()  : mixed
getGlobalConfig()  : mixed
getLogDir()  : mixed
getModule()  : mixed
getRootDir()  : mixed
getSubscribedEvents()  : array<string, string|array{0: string, 1: int}|array<int, array{0: string, 1?: int}>>
Returns an array of event names this subscriber wants to listen to.
getTestsDir()  : mixed
hasModule()  : mixed
persist()  : mixed
receiveModuleContainer()  : mixed
isStepIgnored()  : bool
write()  : mixed
writeln()  : mixed
appendErrorMessage()  : mixed
getTestName()  : string

Properties

$events

public static array<string|int, mixed> $events = [\Codeception\Events::SUITE_BEFORE => 'beforeSuite', \Codeception\Events::SUITE_AFTER => 'afterSuite', \Codeception\Events::TEST_BEFORE => 'before', \Codeception\Events::TEST_ERROR => 'persist', \Codeception\Events::TEST_FAIL => 'persist', \Codeception\Events::TEST_SUCCESS => 'cleanup', \Codeception\Events::STEP_AFTER => 'afterStep']

$config

protected array<string|int, mixed> $config = ['delete_successful' => true, 'module' => 'WebDriver', 'template' => null, 'animate_slides' => true, 'ignore_steps' => [], 'success_color' => 'success', 'failure_color' => 'danger', 'error_color' => 'dark', 'delete_orphaned' => false, 'include_microseconds' => false]

$errorMessages

protected array<string|int, mixed> $errorMessages = []

$indexTemplate

protected string $indexTemplate = <<<EOF <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Recorder Results Index</title> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <!-- Navigation --> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <div class="navbar-header"> <a class="navbar-brand" href="#">Recorded Tests </a> </div> </nav> <div class="container py-4"> <h1>Record #{{seed}}</h1> <ul> {{records}} </ul> </div> </body> </html> EOF

$indicatorTemplate

protected string $indicatorTemplate = <<<EOF <li data-target="#steps" data-slide-to="{{step}}" class="{{isActive}}"></li> EOF

$recordedTests

protected array<string|int, mixed> $recordedTests = []

$seeds

protected array<string|int, mixed> $seeds

$skipRecording

protected array<string|int, mixed> $skipRecording = []

$slides

protected array<string|int, mixed> $slides = []

$slidesTemplate

protected string $slidesTemplate = <<<EOF <div class="carousel-item {{isActive}}"> <img class="mx-auto d-block mh-100" src="{{image}}"> <div class="carousel-caption {{isError}}"> <h5>{{caption}}</h5> <p>Step finished at <span style="color: #3498db">"{{timeStamp}}"</span></p> </div> </div> EOF

$template

protected string $template = <<<EOF <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Recorder Result</title> <!-- Bootstrap Core CSS --> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"> <style> html, body { height: 100%; } .active { height: 100%; } .carousel-caption { background: rgba(0,0,0,0.8); } .carousel-caption.error { background: #c0392b !important; } .carousel-item { min-height: 100vh; } .fill { width: 100%; height: 100%; text-align: center; overflow-y: scroll; background-position: top; -webkit-background-size: cover; -moz-background-size: cover; background-size: cover; -o-background-size: cover; } .gradient-right { background: linear-gradient(to left, rgba(0,0,0,.4), rgba(0,0,0,.0)) } .gradient-left { background: linear-gradient(to right, rgba(0,0,0,.4), rgba(0,0,0,.0)) } </style> </head> <body> <!-- Navigation --> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <div class="navbar-header"> <a class="navbar-brand" href="../records.html"></span>Recorded Tests</a> </div> <div class="collapse navbar-collapse" id="navbarText"> <ul class="navbar-nav mr-auto"> <span class="navbar-text">{{feature}}</span> </ul> <span class="navbar-text">{{test}}</span> </div> </nav> <header id="steps" class="carousel slide" data-ride="carousel"> <!-- Indicators --> <ol class="carousel-indicators"> {{indicators}} </ol> <!-- Wrapper for Slides --> <div class="carousel-inner"> {{slides}} </div> <!-- Controls --> <a class="carousel-control-prev gradient-left" href="#steps" role="button" data-slide="prev"> <span class="carousel-control-prev-icon" aria-hidden="false"></span> <span class="sr-only">Previous</span> </a> <a class="carousel-control-next gradient-right" href="#steps" role="button" data-slide="next"> <span class="carousel-control-next-icon" aria-hidden="false"></span> <span class="sr-only">Next</span> </a> </header> <!-- jQuery --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script> <!-- Script to Activate the Carousel --> <script> \$('.carousel').carousel({ wrap: true, interval: false }) \$(document).bind('keyup', function(e) { if(e.keyCode==39){ jQuery('a.carousel-control.right').trigger('click'); } else if(e.keyCode==37){ jQuery('a.carousel-control.left').trigger('click'); } }); </script> </body> </html> EOF

$timeStamps

protected array<string|int, mixed> $timeStamps = []

Methods

__construct()

public __construct(mixed $config, mixed $options) : mixed
Parameters
$config : mixed
$options : mixed

_initialize()

You can do all preparations here. No need to override constructor.

public _initialize() : mixed

Also you can skip calling _reconfigure if you don't need to.

_reconfigure()

Pass config variables that should be injected into global config.

public _reconfigure([array<string|int, mixed> $config = [] ]) : mixed
Parameters
$config : array<string|int, mixed> = []

afterSuite()

public afterSuite() : mixed

beforeSuite()

public beforeSuite() : mixed

getCurrentModuleNames()

public getCurrentModuleNames() : mixed

getGlobalConfig()

public getGlobalConfig() : mixed

getModule()

public getModule(mixed $name) : mixed
Parameters
$name : mixed

getSubscribedEvents()

Returns an array of event names this subscriber wants to listen to.

public static getSubscribedEvents() : array<string, string|array{0: string, 1: int}|array<int, array{0: string, 1?: int}>>

The array keys are event names and the value can be:

  • The method name to call (priority defaults to 0)
  • An array composed of the method name to call and the priority
  • An array of arrays composed of the method names to call and respective priorities, or 0 if unset

For instance:

  • ['eventName' => 'methodName']
  • ['eventName' => ['methodName', $priority]]
  • ['eventName' => [['methodName1', $priority], ['methodName2']]]

The code must not depend on runtime state as it will only be called at compile time. All logic depending on runtime state must be put into the individual methods handling the events.

Return values
array<string, string|array{0: string, 1: int}|array<int, array{0: string, 1?: int}>>

hasModule()

public hasModule(mixed $name) : mixed
Parameters
$name : mixed

write()

protected write(mixed $message) : mixed
Parameters
$message : mixed

writeln()

protected writeln(string $message) : mixed
Parameters
$message : string

appendErrorMessage()

private appendErrorMessage(string $testPath, string $message) : mixed
Parameters
$testPath : string
$message : string

        
On this page

Search results