PHPUnit Selenium 2 extension setting cookies - php

I'm trying to set cookies before test but for some reason they are not set.
Here is my example code:
class WebTest extends PHPUnit_Extensions_Selenium2TestCase
{
protected function setUp()
{
$this->setBrowser('firefox');
$this->setBrowserUrl('http://dev.local/');
}
public function testTitle()
{
$session = $this->prepareSession();
$session->cookie()->remove('language_version');
$session->cookie()->add('language_version', 'en')->set();
$this->url('/');
$this->assertEquals('Title in English', $this->title());
}
}
Does anyone know how to do it? Any help greatly appreciated.

I have found an answer to my question in Selenium documentation:
If you are trying to preset cookies before you start interacting with a site and your homepage is large / takes a while to load an alternative is to find a smaller page on the site, typically the 404 page is small (http://example.com/some404page)
Now my tests look something like this:
$this->url('/unit_tests.php');
$this->cookie()->remove('language_version');
$this->cookie()->add('language_version', 'en')->set();
$this->url('/');
$this->assertEquals('Title in English', $this->title());
The /unit_tests.php is an empty PHP file that lets me initially set the cookie for the page.

The cookie shouldn't exist so the remove will fail. Selenium runs the browser with a new empty profile on each run of a test suite.
.

Related

Why are my cookies not persisting in Laravel (using Homestead, Vagrant)?

I've been using Laravel from command prompt in Windows 10, but the difficulty of switching between projects has made me switch to using Homestead. However, in a new project I have started there, I can't for the life of me get cookies to persist.
Here is my current code (for debugging this problem only):
use Illuminate\Support\Facades\Cookie;
// ......
public function __construct(Request $request) {
$customer_id = Cookie::get('customer_id');
if(!$customer_id) {
Cookie::queue('customer_id', time(), 3600);
}
dd($customer_id);
}
Expected output: On consecutive page loads, the visitor will see the same unix timestamp they initially opened the page at (I understand this is not a good way of handling it, again, this is just for reproducing the error.)
Reality: Every pageload will produce a different timestamp.
I've looked up as many discussions as I could find. Solutions that I tried:
Using the Route method of declaring cookies
Using good-old PHP setcookie
Using Cookie:make, and Cookie:forever
Adding 'customer_id' in the exceptions among EncryptCookies
Placing the route in the web middleware
Erasing php artisan cache, restarting vagrant
Making the session folder editable through chmod
Yet still, after applying all the above, the cookie is still gone after every page load.
Since I had no prior problem like this through Xampp's PHP, I have to assume there is a (hopefully) trivial and obvious problem with Vagrant that I don't yet know. Any advice is appreciated!
Queued cookies are only sent with responses, so be sure that your controller function does return one.
use Illuminate\Support\Facades\Cookie;
// ......
public function __construct(Request $request) {
$customer_id = Cookie::get('customer_id');
if(!$customer_id) {
Cookie::queue('customer_id', time(), 3600);
}
}
public function foo() {
...
return response('some text');
}
Also, if using some kind of api you have to add a middleware to include the cookies on the response. See Laravel 5.4 - Cookie Queue

Testing Laravel Service Providers

I'm (we're) creating a package that acts as a core component for our future CMS and of course that package needs some unit tests.
When the package registeres, the first thing it does is set the back/frontend context like this:
class FoundationServiceProvider extends ServiceProvider
{
// ... stuff ...
public function register()
{
// Switch the context.
// Url's containing '/admin' will get the backend context
// all other urls will get the frontend context.
$this->app['build.context'] = request()->segment(1) === 'admin'
? Context::BACKEND
: Context::FRONTEND;
}
}
So when I visit the /admin url, the app('build.context') variable will be set to backend otherwise it will be set to `frontend.
To test this I've created the following test:
class ServiceProviderTest extends \TestCase
{
public function test_that_we_get_the_backend_context()
{
$this->visit('admin');
$this->assertEquals(Context::BACKEND, app('build.context'));
}
}
When I'm running the code in the browser (navigating to /admin) the context will get picked up and calling app('build.context') will return backend, but when running this test, I always get 'frontend'.
Is there something I did not notice or some incorrect code while using phpunit?
Thanks in advance
Well, this is a tricky situation. As I understand it, laravel initiates two instances of the framework when running tests - one that is running the tests and another that is being manipulated through instructions. You can see it in tests/TestCase.php file.
So in your case you are manipulating one instance, but checking the context of another (the one that did not visit /admin and is just running the tests). I don't know if there's a way to access the manipulated instance directly - there's nothing helpful in documentation on this issue.
One workaround would be to create a route just for testing purposes, something like /admin/test_context, which would output the current context, and the check it with
$this->visit('admin/test_context')->see(Context::BACKEND);
Not too elegant, but that should work. Otherwise, look around in laravel, maybe you will find some undocumented feature.

PHP MVC - session not persisting

I'm building my own MVC framework in order to learn the ropes properly.
Ive managed to get a login system working, but sessions dont seem to be persisting across page changes.
Ive done some reason reading around and am running session_start() in the controller as a few people seem to be directing.
On login, my processLogin method runs successfully and stores the session data as expected. I know this has happened because Im doing a var_dump on it in the main header file and its there when the login form loads (im not destroying it at any point).
The trouble I have is when it comes to do a location change after successful login, it runs the 'gallery' method, the session array is still there, but empty.
Its exasperating and Id really appreciate any help.
Heres my extended controller class for reference:
session_start();
class Home extends Controller {
public function index() {
require 'application/views/_templates/header.php';
require 'application/views/home/index.php';
require 'application/views/_templates/footer.php';
}
// login function (validation carried out client side)
public function processLogin() {
if (isset($_POST['loginUsername'])) {
$home_model = $this->loadModel("HomeModel");
$home_model->processLogin($_POST['loginUsername'], $_POST['loginPassword']);
}
}
public function gallery() {
require 'application/views/_templates/header.php';
require 'application/views/home/gallery.php';
require 'application/views/_templates/footer.php';
}
}
First thing you should use session_start() at the beginning of main file, usually index.php and not in Controller (because we don't know how your framework is build.
You should make sure that everywhere in your webpage you use the same domain - for example with www. or without www. Otherwise you should use session_set_cookie_params() to set it other way (for example for all subdomains)

How do I run a PHPUnit Selenium test without having a new browser window run for each function?

I am trying to run a selenium test case using PHPUnit. And the first thing I do is trying the login function, this works perfect but then I want to run a function to check information on the page following the login but it opens a new browser instead of continuing in the current browser window. The reason this is a problem is because the page is setup to remove login authentication when the window is closed so if you use $this->url() to go to the page it gives the error that I need to login. This is my code right now, It starts the browser and runs the function to test the login form, then it closes the browser, open a new one and run the link check. This of course results in an error due to the authentication error because the window was closed. I could run all the tests in one function but that is really sloppy coding and I want to avoid this. Anyone know how to solve this?
<?php
class TestMyTest extends PHPUnit_Extensions_Selenium2TestCase {
public function setUp()
{
$this->setBrowser("firefox");
$this->setBrowserUrl("https://**************************");
}
public function testLoginForm()
{
$this->url("login.php");
$this->byLinkText('Forgot your password?');
$form = $this->byCssSelector('form');
$this->byName('username')->value('test');
$this->byName('password')->value('1234');
$form->submit();
}
public function testCheckForMainMenueLinks ()
{
$this->url("index.php");
$this->byLinkText('Home');
$this->byLinkText('Products');
$this->byLinkText('About us');
$this->byLinkText('Contact');
}
}
?>
To share browser sessions in Selenium2TestCase, you must set sessionStrategy => 'shared' in your initial browser setup:
public static $browsers = array(
array(
'...
'browserName' => 'iexplorer',
'sessionStrategy' => 'shared',
...
)
);
The alternative (default) is 'isolated'.
Okej so I guess you can just call the function directly from another function like so:
public function testOne
{
#code
$this->Two();
}
public function Two()
{
#code
$this->Three();
}
public function Three()
{
#code
}
and so on, this will just run the next function without a new browser, however, if it fails anywhere in any test the whole test is stoped so the feedback wont bee as good as individual tests.
make assetrions in one function because this is functional test.
i am new to phpunit and selenium too, but I successfully test all in one like this:
public function testAuth(){
$this->open('register.php&XDEBUG_SESSION_START=PHPSTORM');
$this->assertTextPresent('Register');
$this->type('name=email', "...");
$this->type('name=firstname', "...");
$this->type('name=lastname', "...");
$this->type('name=password', "...");
$this->type('name=verifyPassword', "...");
$this->click("reg-butt");
$this->waitForPageToLoad("5000");
$this->assertTextPresent('Profile');
$this->open('logout.php');
$this->assertTextPresent('text from redirect page');
$this->open('login.php');
.....
}
An elegant way to set the session shared is to use PHPUnit's setUpBeforeClass() method:
public static function setUpBeforeClass()
{
self::shareSession(true);
}
You can call PHPUnit_Extensions_SeleniumTestCase::shareSession(true) to enable browser window reuse.
In the manual it says:
From Selenium 1.1.1, an experimental feature is included allowing the user to share the session between tests. The only supported case is to share the session between all tests when a single browser is used. Call PHPUnit_Extensions_SeleniumTestCase::shareSession(true) in your bootstrap file to enable session sharing. The session will be reset in the case of not successul tests (failed or incomplete); it is up to the user to avoid interactions between tests by resetting cookies or logging out from the application under test (with a tearDown() method).

CodeIgniter: Can't Get My New Controller/View To Show

I am learning how to use codeIgniter as my php framework. I am reading through the documentation and watching the intro video and just generally following along with the first tutorial, but it's not working for me.
I have created a controller called "test.php" and a view called "test_view". The controller for this class is exactly like "welcome.php" and the view file just has some static html. However, when I go to index.php/test I get a 404 error.
I have also tried manipulating the original welcome files so that instead of calling a view it just echos "testing", yet I still see the original welcome message! I've tried clearing my browsing cash and refreshing, but to no avail.
Any suggestions? Thanks.
Edit: Here's the code for controllers/test.php
<?php
class Test extends Controller {
//Just trying to get it to echo test
public function index()
{
echo "test";
//$this->load->view('test_view');
}
}
?>
Try looking at this page in the documentation - this might solve your problem.
This basically means you should try typing index.php?/test/ instead (notice the question-mark).
First of all, check the above link. Might be useful.
If not, then...
Try changing the default controller in the config file ('routes.php') to something else (probably, to 'test'), then try loading index.php. Just to test whether the whole system works (or not).
Check whether mod_rewrite is loaded (in your server .conf-file, if you're using Apache).
Try using the latest build of the framework. AFAIK, the name of the controller class for now is "CI_Controller".
Finally, try removing the word 'public' before the declaration of the function. AFAIR, CI enable you to make private functions in controllers just by using prefix (which is set in the config file) at the beginning of the name of the function (thus making all the other functions public).
But most certainly the problem is with the mod_rewrite. If not, try debugging with die('Page found'); instead of echo - this will allow you to track possible redirects on the page.

Categories