Cannot access PHPUNIT_SELENIUM_TEST_ID cookie in PHPUnit Coverage - selenium

To use phpunit_coverage.php I need to set auto_prepend_file and auto_append_file properties in php.ini to specified files prepend.php and append.php. In both scripts cookies are checked to make sure that test is running:
if ( isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) &&
The problem is that this cookie is kept as localhost's cookie, not the webserver's. So when it is checked, it is not set and xdebug doesn't start.
Selenium and webserver are located on different machines, could this be the cause of this error?
Situation is displayed here:

Similar issue. I thought at first of a domain problem as the tested web site is on a vhost.
But I found out that calling $this->url('some_url') seemed to silently delete the PHPUNIT_SELENIUM_TEST_ID cookie.
My workaround was overriding the url() method in my test cases, in order to reset the cookie once url() is called.
protected function url($url =null)
{
try {
$cookie = $this->cookie()->get('PHPUNIT_SELENIUM_TEST_ID');
}
catch (Exception $e) {}
$result = parent::url($url);
if (isset($cookie)) {
$this->cookie()->add('PHPUNIT_SELENIUM_TEST_ID', $cookie)->set();
}
return $result;
}
The code coverage files are now correctly created.

Related

How do i use Behat with Mink and WebApiContext?

The project i'm working on has a api behind a login.
I'm using behat with mink to login:
Scenario: Login
Given I am on "/login/"
And I should see "Login"
When I fill in "_username" with "test"
And I fill in "_password" with "test"
And I press "_submit"
Then I should be on "/"
This works..
However, the login session is not stored whenever i want to do the following using the WebApiContext:
Scenario: Getting the list of pages
When I send a GET request to "/api/pages.json"
Then print response
I'm using both scenarios in the same feature. My FeatureContext class looks something like this:
class FeatureContext extends MinkContext
{
public function __construct(array $parameters)
{
$context = new WebApiContext($parameters['base_url']);
$context->getBrowser()->getClient()->setCookieJar(new \Buzz\Util\CookieJar());
$this->useContext('web', $context);
}
}
I added the cookiejar idea from this issue without success.. When i print the response i just see the HTML page from the login screen..
Does anyone have any idea if i'm going at this totally the wrong way or am i somewhat in the right direction?
I am successfully using the same method. I don't think there's a standard way of doing this. As far as you understand the cookie basics you should be able to implement the solution.
In a common scenario, a client sends an authentication request to the server with some credentials, the servers validates it, starts an authenticated session and sends back a cookie with that session id. All following requests contain that id, so the server can recognise the callee. A specific header can be used instead of the cookie, or a database can be used instead of the session, but the principle is the same and you can (relatively) easily simulate it with Mink.
/**
* Start a test session, set the authenticated user and set the client's cookie.
*
* #Given /^I am signed in$/
*/
signIn()
{
session_start();
$_SESSION['user'] = 'jos';
$this->getSession()->getDriver()->setCookie(session_name(), session_id());
session_commit();
}
The above step definition (Behat 3) is the basics of it, you manually create the authenticated session and set to the client it's id. That must be also what the other example illustrates.
PHP's sessions can be problematic when you start doing more complex things and there are a couple of big underwater rocks with this solution. If you want to run assertions from both perspectives (the client and the server) you might often need to have your sessions synced. This can be done by updating the cookie before all Mink steps and reloading the session after.
/**
* #beforeStep
* #param BeforeStepScope $scope
*/
public function synchroniseClientSession(BeforeStepScope $scope)
{
// Setup session id and Xdebug cookies to synchronise / enable both.
$driver = $this->getSession()->getDriver();
// Cookie must be set for a particular domain.
if ($driver instanceof Selenium2Driver && $driver->getCurrentUrl() === 'data:,') {
$driver->visit($this->getMinkParameter('base_url'));
}
// Also enables the debugging support.
$driver->setCookie(session_name(), session_id());
$driver->setCookie('XDEBUG_SESSION', 'PHPSTORM');
}
/**
* #afterStep
* #param AfterStepScope $scope
*/
public function synchroniseServerSession(AfterStepScope $scope)
{
$driver = $this->getSession()->getDriver();
// Only browser kit driver, only initiated requests, only not repeating requests.
if (!$driver instanceof BrowserKitDriver) {
return;
} elseif (($request = $driver->getClient()->getRequest()) === null) {
return;
} elseif ($request === self::$request) {
return;
}
// Your logic for reloading the session.
self::$request = $request;
}
The biggest problem I had was the session reloading. This might be due to my framework of choice, which I doubt. The very first code snippet has session_commit(), which saves and closes the session. In theory in the following step definitions you must be able to session_id(/* session id from the cookie… */); and session_start();, but in practice that didn't work and no session data was actually loaded from the file, though the session did start. To solve this I created a custom session manager with reload() method using session save handler.
Second problem is where you cannot simply close the session without either writing it or destroying it (the support is added in PHP 5.6) on which relies the reloading itself. I reinvented the wheel with a flag for the session manager which tells it whether to write or just to close it.
:)

Symfony2 : Failed to start the session because headers have already been sent

TL;DR
Getting an error on a Linux box with Nginx / PHP-FPM stating "Failed to start the session because headers have already been sent.". Error is not occurring on Apache local machine setup
So on my local machine I have the Symfony2 app running fine. No errors are popping up. But as soon as I deploy to our Linux Server I'm getting this error when I call a certain Action within a Controller class
Failed to start the session because headers have already been sent.
In the index action I have already called
$session = $this->getRequest()->getSession();
And in another action within the same controller class I'm calling it again. The error pops up when I try a
$session->set('foo', $bar);
In my Twig I'm calling the action by a form and a button with a formaction property like so
<form id='blahblah'>
.... some fields here .....
<button type='submit' formaction='{{path('2ndAction')}}'></a>
</form>
So on my local machine, running Apache everything run fine. The Linux server is using Nginx and php-fpm and it's crashing for some reason. I checked the phpInfo() and the session auto start is set to off. Not sure if this is an Nginx/php-fpm issue or not but I thought it may be pertinent information.
Here is the Controller declaration, indexAction(), and my 2ndAction()
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use CBSi\Utils\HTTPUtils\CURLUtil;
class StartController extends Controller
{
/**
* #var CurlUtil $curlUtil
*/
private $curlUtil;
/**
* #var AccessControl $accessControl
*/
private $accessControl;
/*placeholder for request object*/
private $requestHolder;
/**
* #Route("/path/for/action/one", name="start")
* #Template()
*/
public function indexAction()
{
$session = $this->getRequest()->getSession();
$this->curlUtil = $this->get('curlUtil');
$this->requestHolder= Request::createFromGlobals();
// Some logic is done here
return $this->render('ListEngagementBundle:Start:start.html.twig');
}
/**
* #Route("/path/to/second/action", name="2ndAction")
* #Template
*/
public function 2ndAction(){
$session = $this->getRequest()->getSession();
$this-> curlUtil = $this->get('curlUtil');
$this->requestHolder= Request::createFromGlobals();
//Some logic is done here to get the data for the session variable
$bar= logic output
$session->set('foo', $bar);
return $this->redirect($this->generateUrl('start'));
}
}
If you need more info that I can provide I will :)
So I figured it out. In the 2nd action where I was calling
$session->getRequest()->getSession();
I had to change that to
$session = new Session();
$session->start();
Go figure. :P
I've get the same error. But in my case I've placed some spaces in the AppKernel.php before the < ?php
tag. So if someone else get this error, checkout if you have some spaces or tabs before in first line of each .php file which get loaded before session get initialized.
This happens to me when in some of the scripts that anticipate $this->session->start();
there is a echo statement!
Hope this can help someone else debugging the issue
I was getting this error message every time I tried to update my database schema using symfony console and when I tried to install new dependencies using composer:
[RuntimeException]
Failed to start the session because headers have already been sent by "/var
/www/html/pulsar283/src/MyService/Local/Brasil.php" at line 153.
So, I went for check the file , and, on line 152 I found a " ?> " (php close tag ).
So, to I just remove the php close tag and the error never shown again !

RavenDB in embedded mode - Raven Silverlight Studio (Raven.Studio.xap) not working

I have a small console application doing some persistence with Raven which is working fine, but I just can't get the Raven Studio Web-App working.
I think I have read every article/blog post on the web which is around, but I haven't got it working.
The project is referencing the Raven.Client.Embedded, Raven.Client.Lightweight and Raven.Storage.Esent assemblies)
Here is the really simple code starting up my console app:
class Program
{
static void Main(string[] args)
{
EmbeddableDocumentStore store = new EmbeddableDocumentStore { DataDirectory = #"C:\temp\ravendata", UseEmbeddedHttpServer = true };
store.Initialize();
Console.WriteLine("Initialized");
while (true)
{
string line = Console.ReadLine();
if (line == "w")
{
Changeset cs = CreateChangeset();
using (var session = store.OpenSession())
{
session.Store(cs);
session.SaveChanges();
}
Console.WriteLine("Written.");
}
}
The question is: Where to put the Raven.Studio.xap in order to get it running in the browser (http://localhost:8080/Raven/studio.html)?
It's not working in the bin/debug output folder of my console app (which would be the most logical area where it should be), as well as it isn't if I put it in the root of my console application.
Sorry to ask this thing again, but it seems there is some point I am missing on this to get it up and running. ;)
Thanks for your help, R's, Rene
You are right, I've tried it using a new console application project and had the same issues, altough I copied the file Raven.Studio.xap into the \bin\debug AFTER I had seen the error message for the first time.
I found out, that the reason for this has to do with browser-caching. Even though the file would be available now, the embedded http-server returns 304 Not Modified, because it had sent the If-None-Match header into the request. Therefore, the cached "not-found" page in the browser cache will be used.
I fixed it and sent a patch to Ayende. However the solution now is:
1) make sure Raven.Studio.xap is under \bin\debug
2) clear the browsers cache

Can I configure Apache to redirect at a specified timeout?

I How to configure Apache so I can redirect to another page on a specified TimeOut. Is this possible?
Didn't find any possible solution how to do this in Apache.
Still, if you are using PHP, try playing with PHP register_shutdown_function function.
Sample code:
set_time_limit(1);
function shutdown () {
if ( ! defined('FINISHED')) {
header('Location: /timeout');
}
}
register_shutdown_function('shutdown');
while (true) {}
define('FINISHED', 1);
Still this will be executed on fatal errors as well and after manual die() or exit() calls inside your scripts.

Sharepoint 2010 FBA Custom Login Page 403 Error

I followed the tutorial below to create a custom login page for my Claims SP2010 site.
http://blogs.msdn.com/b/kaevans/archive/2010/07/09/creating-a-custom-login-page-for-sharepoint-2010.aspx
But all I get is a 403 FORBIDDEN text in Firefox. No luck in IE too. I searched over web for a couple of hours but still no luck.
Anyone experienced this situtation before?
Thanks.
According to the referenced blog post, your custom login page should inherit from FormsSignInPage. I took a look at the class in Reflector and did not see anything that would cause a 403 error. However, in looking at its parent, IdentityModelSignInPageBase, I found the following in the OnLoad method:
protected override void OnLoad(EventArgs e)
{
this.Context.Request.ServerVariables["FederationLoginPageRequest"] = "1";
if (this.CheckForFormsAccess
&& (AuthenticationMode.Forms != SPSecurity.AuthenticationMode))
{
SPUtilityInternal.Send403(this.Context);
}
if (!this.AllowCaching)
{
base.Response.Cache.SetNoStore();
}
base.ShowStandardControls = false;
base.OnLoad(e);
}
CheckForFormsAccess is always true, so make sure your Authentication Mode is set to forms.
You are probably being redirected to 403, because anonymous user not having access to display the custom error page.
Log files can give you a clue on why is that happening.
Alternatively:
In web.config files (one for the web application & the one in _layouts folder) set the following:
CustomErrors="Off"
Debug="true"
Callstack="true"