Instantly share code, notes, and snippets.

Embed
What would you like to do?
Using the Behat Drupal Extension on sites with basic auth
<?php
/**
* Run before every scenario.
*
* @BeforeScenario
*/
public function beforeScenario() {
if ($basic_auth = $this->getDrupalParameter('basic_auth')) {
$driver = $this->getSession()->getDriver();
if ($driver instanceof Selenium2Driver) {
// Continue if this is a Selenium driver, since this is handled in
// locatePath().
}
else {
// Setup basic auth.
$this->getSession()->setBasicAuth($basic_auth['username'], $basic_auth['password']);
}
}
}
/**
* Override MinkContext::locatePath() to work around Selenium not supporting
* basic auth.
*/
public function locatePath($path) {
$driver = $this->getSession()->getDriver();
if ($driver instanceof Selenium2Driver && $basic_auth = $this->getDrupalParameter('basic_auth'))\
{
// Add the basic auth parameters to the base url. This only works for
// Firefox.
$startUrl = rtrim($this->getMinkParameter('base_url'), '/') . '/';
$startUrl = str_replace('://', '://' . $basic_auth['username'] . ':' . $basic_auth['password']\
. '@', $startUrl);
return 0 !== strpos($path, 'http') ? $startUrl . ltrim($path, '/') : $path;
}
else {
return parent::locatePath($path);
}
}
@jbickar

This comment has been minimized.

Copy link

jbickar commented Dec 20, 2015

Surprisingly tricky. The Googles led me to this gist, which actually didn't work for me. But setting:

base_url: https://username:pass@example.com

in behat.yml did. YMMV.

@nephel

This comment has been minimized.

Copy link

nephel commented Jan 13, 2016

good tip @jbickar - worked for me too

@asherry

This comment has been minimized.

Copy link

asherry commented Jul 30, 2016

the problem I'm having is that after form submit, the page redirects and it doesn't keep the 'username:pass' part. Is that a problem with the site code or something I can do in the behat config?

@batigolix

This comment has been minimized.

Copy link

batigolix commented Mar 24, 2017

I'm using this method in FeatureContext.php to do basic auth login:

  /**
   * Run before every scenario.
   *
   * @BeforeScenario
   */
  public function beforeScenario() {
    $this->getSession()->setBasicAuth('boris', 'secret');
  }
@shrop

This comment has been minimized.

Copy link

shrop commented Feb 20, 2018

@batigolix, that is great ^^. I enhanced what you did by receiving the basic auth username and password with env vars. A bit better security so those don't have to get committed to repos.

/**
 * Run before every scenario tagged.
 *
 * @BeforeScenario
 */
public function beforeScenario() {
  $username = $_SERVER['BASIC_AUTH_USER'];
  $password = $_SERVER['BASIC_AUTH_PASS'];

  if (!empty($username) && !empty($password)) {
    $this->getSession()->setBasicAuth($username, $password);
  }
}

Run test

BASIC_AUTH_USER=<username> BASIC_AUTH_PASS=<passwprd> behat
@PapaGrande

This comment has been minimized.

Copy link

PapaGrande commented Apr 13, 2018

A small tweak to @shrop's code to make the basic auth credentials optional in the command line:

  /**
   * Run before every scenario tagged.
   *
   * @BeforeScenario
   */
  public function beforeScenario() {
    $username = (isset($_SERVER['BASIC_AUTH_USER']) ? $_SERVER['BASIC_AUTH_USER'] : NULL);
    $password = (isset($_SERVER['BASIC_AUTH_PASS']) ? $_SERVER['BASIC_AUTH_PASS'] : NULL);

    if (!empty($username) && !empty($password)) {
      $this->getSession()->setBasicAuth($username, $password);
    }
  }
@ey-

This comment has been minimized.

Copy link

ey- commented Oct 22, 2018

In case someone has the same issue.
Recently we had the following Exception using the snippet from @PapaGrande.

 Behat\Testwork\Call\Exception\FatalThrowableError: Fatal error: Call to a member function send() on null in /var/www/vendor/dmore/chrome-mink-driver/src/ChromeDriver.php:1330

This was caused by a not started session prior to using setBasicAuth.

The solution here is to check if the session is started, and if not start it. Resulting into the following:

 /**
   * Run before every scenario tagged.
   *
   * @BeforeScenario
   */
  public function beforeScenario() {
    $username = (isset($_SERVER['APACHE_BASIC_AUTH_USER']) ? $_SERVER['APACHE_BASIC_AUTH_USER'] : NULL);
    $password = (isset($_SERVER['APACHE_BASIC_AUTH_PASS']) ? $_SERVER['APACHE_BASIC_AUTH_PASS'] : NULL);

    if (!empty($username) && !empty($password)) {
      $session = $this->getSession();
      if (!$session->isStarted()) {
        $session->start();
      }
      $session->setBasicAuth($username, $password);
    }
  }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment