Last active
June 24, 2021 12:55
-
-
Save jhedstrom/5bc5192d6dacbf8cc459 to your computer and use it in GitHub Desktop.
Using the Behat Drupal Extension on sites with basic auth
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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); | |
} | |
} |
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');
}
@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
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);
}
}
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
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?