palantirnet / palantir-behat-extension

Additional step definitions for testing Drupal sites using Behat.
1 stars 4 forks source link

add screenshots and html dumps for debugging #33

Open becw opened 7 years ago

becw commented 7 years ago

Some of these things will be useful...

<?php

use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Behat\Hook\Scope\AfterStepScope;
use Behat\Behat\Hook\Scope\AfterScenarioScope;
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Behat\Gherkin\Node\TableNode;
use Behat\Mink\Exception\ExpectationException;
use Drupal\DrupalExtension\Context\DrupalContext;
use Drupal\DrupalExtension\Context\MinkContext;
use Drupal\DrupalExtension\Context\RawDrupalContext;

/**
 * Defines application features from the specific context.
 */
class FeatureContext extends RawDrupalContext implements SnippetAcceptingContext
{
    /** @var String The directory to save screenshots and html to. */
    private $debug_dir;

    /**
     * @var MinkContext
     */
    private $minkContext;

    /**
     * @var DrupalContext
     */
    private $drupalContext;

    /**
     * @var array of tid's for Forums created in tests.
     */
    private $forums = [];

    /**
     * Initializes context.
     */
    public function __construct()
    {
        $this->debug_dir = __DIR__ . '/../../debug/';
    }

    /**
     * @AfterStep
     *
     * @param \Behat\Behat\Hook\Scope\AfterStepScope $event
     */
    public function printLastResponseOnError(AfterStepScope $event)
    {
        if (!$event->getTestResult()->isPassed()) {
            $this->saveHtml();
        }
    }

    /**
     * Grab the html of the page and save it.
     *
     * @Then save the html for the page
     * @Then save the html for the page with prefix :prefix
     *
     * @param string $prefix A string to prepend to the filename.
     */
    public function saveHtml($prefix = 'html') {
        $html_data = $this->getSession()->getDriver()->getContent();
        $filename = $this->debug_dir . $prefix . '-' .  time() . '.html';
        file_put_contents($filename, $html_data);
    }

    /**
     * Grab a screenshot of the page and save it.
     *
     * @Then save a screenshot of the page
     * @Then save a screenshot of the page with prefix :prefix
     *
     * @param string $prefix A string to prepend to the filename.
     */
    public function saveAScreenshot($prefix = 'screenshot')
    {
        $screenshot = $this->getSession()->getDriver()->getScreenshot();
        $filename = $this->debug_dir . $prefix . '-' . time() . '.png';
        file_put_contents($filename, $screenshot);
    }

    /**
     * @BeforeScenario
     */
    public function gatherContexts(BeforeScenarioScope $scope)
    {
        $environment = $scope->getEnvironment();
        $this->drupalContext = $environment->getContext(DrupalContext::class);
        $this->minkContext = $environment->getContext(MinkContext::class);
    }

  /**
   * Click on the element with the provided xpath query
   *
   * @When /^(?:|I )click on the element "([^"]*)"$/
   */
  public function iClickOnTheElement($arg)
  {
      $session = $this->getSession(); // get the mink session
      $element = $session->getPage()->find('css', $arg); // runs the actual query and returns the element

      // errors must not pass silently
      if (null === $element) {
          throw new \InvalidArgumentException(sprintf('Could not evaluate CSS selector: "%s"', $arg));
      }

      // ok, let's click on it
      $element->click();
  }

  /**
   * Some forms do not have a Submit button just pass the ID
   *
   * @Given /^I submit the form with id "([^"]*)"$/
   */
  public function iSubmitTheFormWithId($arg) {
      $session = $this->getSession();
      $element = $session->getPage()->find('css', $arg);
      if($element) {
          $element->submit();
      } else {
          throw new Exception('Element not found');
      }
  }

  /**
   * @param int $seconds
   *   Amount of seconds when nothing to happens.
   *
   * @Given /^(?:|I )wait (\d+) seconds$/
   */
  public function waitSeconds($seconds)
  {
    sleep($seconds);
  }