Completed
Push — 1.0.x ( f8d28b...3b754a )
by Antonio
06:23
created

ScreenShotContext::takeScreenshot()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
3
namespace NuvoleWeb\Drupal\DrupalExtension\Context;
4
5
use Behat\Mink\Driver\Selenium2Driver;
6
use Behat\Behat\Context\Environment\InitializedContextEnvironment;
7
use Behat\Behat\Hook\Scope\AfterStepScope;
8
use Behat\Mink\Exception\DriverException;
9
10
/**
11
 * Class ScreenShotContext.
12
 *
13
 * @package NuvoleWeb\Drupal\DrupalExtension\Context
14
 */
15
class ScreenShotContext extends RawMinkContext {
16
17
  /**
18
   * Save screenshot with a specific name.
19
   *
20
   * @Then (I )take a screenshot :name
21
   */
22
  public function takeScreenshot($name = NULL) {
23
    $file_name = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $name;
24
    $message = "Screenshot created in @file_name";
25
    $this->createScreenshot($file_name, $message, FALSE);
26
  }
27
28
  /**
29
   * Save screenshot.
30
   *
31
   * @Then (I )take a screenshot
32
   */
33
  public function takeScreenshotUnnamed() {
34
    $file_name = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'behat-screenshot';
35
    $message = "Screenshot created in @file_name";
36
    $this->createScreenshot($file_name, $message);
37
  }
38
39
  /**
40
   * Make sure there is no PHP notice on the screen during tests.
41
   *
42
   * @AfterStep
43
   */
44
  public function screenshotForPhpNotices(AfterStepScope $event) {
45
    $environment = $event->getEnvironment();
46
    // Make sure the environment has the MessageContext.
47
    $class = 'Drupal\DrupalExtension\Context\MessageContext';
48
    if ($environment instanceof InitializedContextEnvironment && $environment->hasContextClass($class)) {
49
      /** @var \Drupal\DrupalExtension\Context\MessageContext $context */
50
      $context = $environment->getContext($class);
51
      // Only check if the session is started.
52
      try {
53
        if ($context->getMink()->isSessionStarted()) {
54
          try {
55
            $context->assertNotWarningMessage('Notice:');
56
          }
57
          catch (\Exception $e) {
58
            // Use the step test in the filename.
59
            $step = $event->getStep();
60 View Code Duplication
            if (function_exists('transliteration_clean_filename')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
61
              $file_name = transliteration_clean_filename($step->getKeyword() . '_' . $step->getText());
62
            }
63
            else {
64
              $file_name = str_replace(' ', '_', $step->getKeyword() . '_' . $step->getText());
65
              $file_name = preg_replace('![^0-9A-Za-z_.-]!', '', $file_name);
66
            }
67
            $file_name = substr($file_name, 0, 30);
68
            $file_name = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'behat-notice__' . $file_name;
69
            $message = "Screenshot for behat notice in step created in @file_name";
70
            $this->createScreenshot($file_name, $message);
71
            // We don't throw $e any more because we don't fail on the notice.
72
          }
73
        }
74
      }
75
      catch (DriverException $driver_exception) {
76
77
      }
78
    }
79
  }
80
81
  /**
82
   * Take a screenshot after failed steps or save the HTML for non js drivers.
83
   *
84
   * @AfterStep
85
   */
86
  public function takeScreenshotAfterFailedStep(AfterStepScope $event) {
87
    if ($event->getTestResult()->isPassed()) {
88
      // Not a failed step.
89
      return;
90
    }
91
    try {
92
      $step = $event->getStep();
93 View Code Duplication
      if (function_exists('transliteration_clean_filename')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
94
        $file_name = transliteration_clean_filename($step->getKeyword() . '_' . $step->getText());
95
      }
96
      else {
97
        $file_name = str_replace(' ', '_', $step->getKeyword() . '_' . $step->getText());
98
        $file_name = preg_replace('![^0-9A-Za-z_.-]!', '', $file_name);
99
      }
100
      $file_name = substr($file_name, 0, 30);
101
      $file_name = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'behat-failed__' . $file_name;
102
      $message = "Screenshot for failed step created in @file_name";
103
      $this->createScreenshot($file_name, $message);
104
    }
105
    catch (DriverException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
106
107
    }
108
  }
109
110
  /**
111
   * Create a screenshot or save the html.
112
   *
113
   * @param string $file_name
114
   *   The filename of the screenshot (complete).
115
   * @param string $message
116
   *   The message to be printed. @file_name will be replaced with $file name.
117
   * @param bool|true $ext
118
   *   Whether to add .png or .html to the name of the screenshot.
119
   */
120
  public function createScreenshot($file_name, $message, $ext = TRUE) {
121
    if ($this->getSession()->getDriver() instanceof Selenium2Driver) {
122
      if ($ext) {
123
        $file_name .= '.png';
124
      }
125
      $screenshot = $this->getSession()->getDriver()->getScreenshot();
126
      file_put_contents($file_name, $screenshot);
127
    }
128
    else {
129
      if ($ext) {
130
        $file_name .= '.html';
131
      }
132
      $html_data = $this->getSession()->getDriver()->getContent();
133
      file_put_contents($file_name, $html_data);
134
    }
135
    if ($message) {
136
      print strtr($message, ['@file_name' => $file_name]);
137
    }
138
  }
139
140
}
141