New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Behat 3: Taking screenshots after failed steps #649

Closed
BentCoder opened this Issue Oct 21, 2014 · 8 comments

Comments

Projects
None yet
3 participants
@BentCoder

BentCoder commented Oct 21, 2014

Code below works fine for Behat 2 but it doesn't for Behat 3. Does anyone know how to implement it in Behat 3?

_Behat 3 error:_

PHP Fatal error:  Call to undefined method Behat\Behat\Hook\Scope\AfterStepScope::getResult() in behat-three/features/bootstrap/Site/MainBundle/Features/Context/FeatureContext.php on line 65

Line 65 is : if (4 === $event->getResult()) {

_Behat 2 working example_

namespace Site\CommonBundle\Features\Context;

use Behat\MinkExtension\Context\MinkContext;
use Behat\Mink\Exception\UnsupportedDriverActionException;
use Behat\Mink\Driver\Selenium2Driver;
use Behat\Symfony2Extension\Context\KernelAwareInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Process\Process;

class FeatureContext extends MinkContext implements KernelAwareInterface
{
    /**
     * Take screen-shot when step fails. Works only with Selenium2Driver.
     *
     * @AfterStep
     * @param $event Current event.
     * @throws \Behat\Mink\Exception\UnsupportedDriverActionException
     */
    public function takeScreenshotAfterFailedStep($event)
    {
        if (4 === $event->getResult()) {
            $driver = $this->getSession()->getDriver();

            if (! ($driver instanceof Selenium2Driver)) {
                throw new UnsupportedDriverActionException(
                    'Taking screen-shots is not supported by %s, use Selenium2Driver instead.',
                    $driver
                );

                return;
            }

            if (! is_dir($this->screenShotPath)) {
                mkdir($this->screenShotPath, 0777, true);
            }

            $filename = sprintf(
                '%s_%s_%s.%s',
                $this->getMinkParameter('browser_name'),
                date('Ymd') . '-' . date('His'),
                uniqid('', true),
                'png'
            );

            file_put_contents($this->screenShotPath . '/' . $filename, $driver->getScreenshot());
        }
    }
}

@nchagrass

This comment has been minimized.

Show comment
Hide comment
@nchagrass

nchagrass Oct 21, 2014

    /**
     * @AfterStep
     */
    public function takeScreenshotAfterFailedStep(AfterStepScope $scope)
    {
        if (99 === $scope->getTestResult()->getResultCode()) {
            $this->takeScreenshot();
        }
    }

    private function takeScreenshot()
    {
        $driver = $this->getSession()->getDriver();
        if (!$driver instanceof Selenium2Driver) {
            return;
        }
        $baseUrl = $this->getMinkParameter('base_url');
        $fileName = date('d-m-y') . '-' . uniqid() . '.png';
        $filePath = $this->getContainer()->get('kernel')->getRootdir() . '/../web/tmp/';

        $this->saveScreenshot($fileName, $filePath);
        print 'Screenshot at: ' . $baseUrl . 'tmp/' . $fileName;
    }

Something like that works

nchagrass commented Oct 21, 2014

    /**
     * @AfterStep
     */
    public function takeScreenshotAfterFailedStep(AfterStepScope $scope)
    {
        if (99 === $scope->getTestResult()->getResultCode()) {
            $this->takeScreenshot();
        }
    }

    private function takeScreenshot()
    {
        $driver = $this->getSession()->getDriver();
        if (!$driver instanceof Selenium2Driver) {
            return;
        }
        $baseUrl = $this->getMinkParameter('base_url');
        $fileName = date('d-m-y') . '-' . uniqid() . '.png';
        $filePath = $this->getContainer()->get('kernel')->getRootdir() . '/../web/tmp/';

        $this->saveScreenshot($fileName, $filePath);
        print 'Screenshot at: ' . $baseUrl . 'tmp/' . $fileName;
    }

Something like that works

@BentCoder

This comment has been minimized.

Show comment
Hide comment
@BentCoder

BentCoder Oct 21, 2014

That worked well. Thanks.

BentCoder commented Oct 21, 2014

That worked well. Thanks.

@BentCoder BentCoder closed this Oct 21, 2014

@narozhniyy

This comment has been minimized.

Show comment
Hide comment
@narozhniyy

narozhniyy May 29, 2015

Not working for me undefined method getContainer(), which lib did you use? (behat 3)

narozhniyy commented May 29, 2015

Not working for me undefined method getContainer(), which lib did you use? (behat 3)

@BentCoder

This comment has been minimized.

Show comment
Hide comment
@BentCoder

BentCoder May 29, 2015

@narozhniyy If you can wait a bit, I'll give you full example however while waiting, do research on how to use container in FeatureContext files. There are many examples so you might solve your problem yourself.

BentCoder commented May 29, 2015

@narozhniyy If you can wait a bit, I'll give you full example however while waiting, do research on how to use container in FeatureContext files. There are many examples so you might solve your problem yourself.

@narozhniyy

This comment has been minimized.

Show comment
Hide comment
@narozhniyy

narozhniyy May 29, 2015

@BentCoder it's will be great, thanks

narozhniyy commented May 29, 2015

@BentCoder it's will be great, thanks

@narozhniyy

This comment has been minimized.

Show comment
Hide comment
@narozhniyy

narozhniyy Jul 7, 2015

@BentCoder did you forget about me?

narozhniyy commented Jul 7, 2015

@BentCoder did you forget about me?

@BentCoder

This comment has been minimized.

Show comment
Hide comment
@BentCoder

BentCoder Jul 8, 2015

@narozhniyy No I didn't! There seem to be a problem with the library I think because what was working before doesn't want to work anymore hence reason I left a message here #764 but no one got back to me yet. Keep an eye on that issue. Let's wait what they say.

BentCoder commented Jul 8, 2015

@narozhniyy No I didn't! There seem to be a problem with the library I think because what was working before doesn't want to work anymore hence reason I left a message here #764 but no one got back to me yet. Keep an eye on that issue. Let's wait what they say.

@BentCoder

This comment has been minimized.

Show comment
Hide comment
@BentCoder

BentCoder Jul 8, 2015

OK work now!

composer.json

    "require-dev": {
        "behat/behat" : "3.0.15",
        "behat/symfony2-extension" : "2.0.0",
        "behat/mink": "1.6.1",
        "behat/mink-extension": "2.0.1",
        "behat/mink-browserkit-driver": "1.2.0",
        "behat/mink-goutte-driver": "1.1.0",
        "behat/mink-selenium2-driver": "1.2.0"
    },

behat.yml

default:
    extensions:
        Behat\Symfony2Extension: ~
        Behat\MinkExtension:
            base_url: http://football.local/app_test.php
            browser_name: firefox
            sessions:
                goutte:
                    goutte: ~
                selenium2:
                    selenium2: ~
                symfony2:
                    symfony2: ~
    suites:
        backend:
            type: symfony_bundle
            bundle: ApplicationBackendBundle
            mink_session: selenium2
            contexts:
                - Application\BackendBundle\Features\Context\FeatureContext:
                    screen_shot_path: build/phing/behat/screenshot

FeatureContext

namespace Application\BackendBundle\Features\Context;

use Behat\Behat\Hook\Scope\AfterStepScope;
use Behat\Mink\Driver\Selenium2Driver;
use Behat\MinkExtension\Context\MinkContext;

class FeatureContext extends MinkContext
{
    private $screenShotPath;

    public function __construct($screen_shot_path)
    {
        $this->screenShotPath = $screen_shot_path;
    }

    /**
     * Take screen-shot when step fails. Works only with Selenium2Driver.
     *
     * @AfterStep
     * @param AfterStepScope $scope
     */
    public function takeScreenshotAfterFailedStep(AfterStepScope $scope)
    {
        if (99 === $scope->getTestResult()->getResultCode()) {
            $driver = $this->getSession()->getDriver();

            if (! $driver instanceof Selenium2Driver) {
                return;
            }

            if (! is_dir($this->screenShotPath)) {
                mkdir($this->screenShotPath, 0777, true);
            }

            $filename = sprintf(
                '%s_%s_%s.%s',
                $this->getMinkParameter('browser_name'),
                date('Ymd') . '-' . date('His'),
                uniqid('', true),
                'png'
            );

            $this->saveScreenshot($filename, $this->screenShotPath);
        }
    }
}

example feature

Feature: Dummy feature

  Scenario: Home url
    Given I am on "/backend"
    Then I should see "Welcome to Application backend! I will break this test"

Download and run selenium first
First download it (version 2.46.0) and put right into your project folder. http://www.seleniumhq.org/download/

Bc-MBP:football bentcoder$ java -jar selenium-server-standalone-2.46.0.jar

Run test

Bc-MBP:football bentcoder$  bin/behat --suite=backend
Feature: Dummy feature

  Scenario: Home url                                     # src/Application/BackendBundle/Features/Dummy.feature:3
    Given I am on "/backend"                             # Application\BackendBundle\Features\Context\FeatureContext::visit()
    Then I should see "Welcome to Application backend! I will break this test" # Application\BackendBundle\Features\Context\FeatureContext::assertPageContainsText()
      The text "Welcome to Application backend!1" was not found anywhere in the text of the current page. (Behat\Mink\Exception\ResponseTextException)

--- Failed scenarios:

    src/Application/BackendBundle/Features/Dummy.feature:3

1 scenario (1 failed)
2 steps (1 passed, 1 failed)

project folder structure for screenshots

football
   build
      phing
         behat
            screenshots

result

image

BentCoder commented Jul 8, 2015

OK work now!

composer.json

    "require-dev": {
        "behat/behat" : "3.0.15",
        "behat/symfony2-extension" : "2.0.0",
        "behat/mink": "1.6.1",
        "behat/mink-extension": "2.0.1",
        "behat/mink-browserkit-driver": "1.2.0",
        "behat/mink-goutte-driver": "1.1.0",
        "behat/mink-selenium2-driver": "1.2.0"
    },

behat.yml

default:
    extensions:
        Behat\Symfony2Extension: ~
        Behat\MinkExtension:
            base_url: http://football.local/app_test.php
            browser_name: firefox
            sessions:
                goutte:
                    goutte: ~
                selenium2:
                    selenium2: ~
                symfony2:
                    symfony2: ~
    suites:
        backend:
            type: symfony_bundle
            bundle: ApplicationBackendBundle
            mink_session: selenium2
            contexts:
                - Application\BackendBundle\Features\Context\FeatureContext:
                    screen_shot_path: build/phing/behat/screenshot

FeatureContext

namespace Application\BackendBundle\Features\Context;

use Behat\Behat\Hook\Scope\AfterStepScope;
use Behat\Mink\Driver\Selenium2Driver;
use Behat\MinkExtension\Context\MinkContext;

class FeatureContext extends MinkContext
{
    private $screenShotPath;

    public function __construct($screen_shot_path)
    {
        $this->screenShotPath = $screen_shot_path;
    }

    /**
     * Take screen-shot when step fails. Works only with Selenium2Driver.
     *
     * @AfterStep
     * @param AfterStepScope $scope
     */
    public function takeScreenshotAfterFailedStep(AfterStepScope $scope)
    {
        if (99 === $scope->getTestResult()->getResultCode()) {
            $driver = $this->getSession()->getDriver();

            if (! $driver instanceof Selenium2Driver) {
                return;
            }

            if (! is_dir($this->screenShotPath)) {
                mkdir($this->screenShotPath, 0777, true);
            }

            $filename = sprintf(
                '%s_%s_%s.%s',
                $this->getMinkParameter('browser_name'),
                date('Ymd') . '-' . date('His'),
                uniqid('', true),
                'png'
            );

            $this->saveScreenshot($filename, $this->screenShotPath);
        }
    }
}

example feature

Feature: Dummy feature

  Scenario: Home url
    Given I am on "/backend"
    Then I should see "Welcome to Application backend! I will break this test"

Download and run selenium first
First download it (version 2.46.0) and put right into your project folder. http://www.seleniumhq.org/download/

Bc-MBP:football bentcoder$ java -jar selenium-server-standalone-2.46.0.jar

Run test

Bc-MBP:football bentcoder$  bin/behat --suite=backend
Feature: Dummy feature

  Scenario: Home url                                     # src/Application/BackendBundle/Features/Dummy.feature:3
    Given I am on "/backend"                             # Application\BackendBundle\Features\Context\FeatureContext::visit()
    Then I should see "Welcome to Application backend! I will break this test" # Application\BackendBundle\Features\Context\FeatureContext::assertPageContainsText()
      The text "Welcome to Application backend!1" was not found anywhere in the text of the current page. (Behat\Mink\Exception\ResponseTextException)

--- Failed scenarios:

    src/Application/BackendBundle/Features/Dummy.feature:3

1 scenario (1 failed)
2 steps (1 passed, 1 failed)

project folder structure for screenshots

football
   build
      phing
         behat
            screenshots

result

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment