How can I clear cookies for each tests in my PhantomJS + GhostDriver + Selenium WebDriver + WebDriver Client system?
My test process looks like this:
Start selenium-web-driver-standalone in hub role.
Start phantomjs in webdriver mode and attach it to selenium
webdriver.
Start shell script that iterates over tests suites and start each.
Each test uses webdriver client and communicate with browser
connected to selenium web driver.
When I use firefox browser instead of phantomjs all tests passed ok. But when I switch to using phantomjs as browser all tests that checked registration failed because cookies already set after first test execution. Can I clear all cookies on every test start up? Or I should to restart phantomjs process on every separate test (as this is with firefox and selenium webdriver in not hub role)?
Maybe some offtopic, cause author marked that he uses php to run test.
But if you came from google and interested in C# solution to clear all cookies, look below:
// driver is fully initialized PhantomJS instance
driver.Manage().Cookies.DeleteAllCookies();
Requires NuGetPackages:
PhantomJS 2.0.0
Selenium.Support 2.48.2
Selenium.WebDriver 2.48.2
Tested with .NETFramework v4.5.2
You can delete specific cookie using:
webDriver.manage().deleteCookieNamed("smSession");
And to delete all the cookies using:
webDriver.manage().deleteAllCookies();
I had similar problem with GhostDriver not being able to clear localStorage. Try these suggestions:
After you driver.get(URL) to your page, you can execute javascript in
it from webdriver, like this
function clearCookie(name, domain, path){
var domain = domain || document.domain;
var path = path || "/";
document.cookie = name + "=; expires=" + +new Date + "; domain=" + domain + "; path=" + path;
};
There is no 100% solution to delete browser cookies.
The problem is that cookies are uniquely identified by not just by
their key "name" but also their "domain" and "path".
Without knowing the "domain" and "path" of a cookie, you cannot
reliably delete it. This information is not available through
JavaScript's document.cookie. It's not available through the HTTP
Cookie header either!
However, if you know the name, path and domain of a cookie, then you
can clear it by setting an empty cookie with an expiry date in the
past
Resources:
https://sqa.stackexchange.com/a/10468
https://stackoverflow.com/a/2421786/572348
Related
running django locally and with firefox, i login with http://localhost:8000/admin/ and after that i can access http://localhost:8000/myCustomApi successfully.
on insomnia every time i login with http://localhost:8000/admin/ i get {"code": "csrf", "reason": "CSRF cookie not set."} on the response. i tried this but didn't work. is there any tutorial to what should i do?
Install this plugin: https://insomnia.rest/plugins/insomnia-plugin-default-headers
Click on your environment and then on "Manage Environments"
3. In your environment, add a new env var:
{
"DEFAULT_HEADERS": {
"X-CSRFToken": "wSYUpsSIkXxjA8wBiojsCU7YgJGYySGFWiDHNoGhEpCWGxoIyNfIvw7hr2Au1a9J"
}
}
Replace the value with one you can find in your browser.
Now, that was for sending data to forms. If you need to make a request while being loggued, click on Cookies and add a new cookie with a name sessionid and the value that you will find in your browser.
Enjoy
Setting the X-CSRFToken didn't worked for me.
So I tried to "copy" the same request in the Insomnia environment.
In my case, what I did was:
Go to your Browser and do at least one successful request.
Go to Network tab and copy the Request Header with name Cookie.
Go to Insomnia and set this same header with it values.
Try debbugging from Insomnia.
Insomnia:
But if something seems different to you, just keep the same core: copy the request environment from browser to insomnia.
Remember the server can't see difference between an Insomnia client and the Browser if all the headers are the same.
I've got a Next.js application that uses AWS Cognito userpools for authentication. I have a custom UI and am using the aws-amplify package directly invoking signIn/signOut/etc... in my code. (I previously used the AWS Hosted UI and had the same problem set out below - I hoped switching and digging into the actual APIs who reveal my problem but it hasn't)
Everything in development (running on localhost) is working correctly - I'm able to login and get access to my current session both in a page's render function using
import { Auth } from 'aws-amplify';
...
export default const MyPage = (props) => {
useEffect(async () => {
const session = await Auth.currentSession();
...
}
...
}
and during SSR
import { withSSRContext } from 'aws-amplify';
...
export async function getServerSideProps(context) {
...
const SSR = withSSRContext(context);
const session = await SSR.Auth.currentSession();
...
}
However, when I deploy to AWS Amplify where I run my staging environment, the call to get the current session during SSR fails. This results in the page rendering as if the user is not logged in then switching when the client is able to determine that the user is in fact logged in.
Current Hypothesis - missing cookies(??):
I've checked that during the login process that the AWS cookies are being set correctly in the browser. I've also checked and devtools tells me the cookies are correctly being sent to the server with the request.
However, if I log out context.req.headers inside getServerSideProps in my staging environment, the cookie header is missing (whereas in my dev environment it appears correctly). If this is true, this would explain what I'm seeing as getServerSideProps isn't seeing my auth tokens, etc... but I can't see why the cookie headers would be stripped?
Has anyone seen anything like this before? Is this even possible? If so, why would this happen? I assume I'm missing something, e.g. config related, but I feel like I've followed the docs pretty closely - my current conf looks like this
Amplify.configure({
Auth: {...}
ssr: true
});
Next.js version is 11.1.2 (latest)
Any help very much appreciated!
You have to use Next#11.0.0 to use getServerSideProps, withSSRContext and Auth module in production.
I had same issue.
My solution was that disconnect a branch has an authentication problem once and reconnect the branch.
What are your build settings? I guess you are using next build && next export in which case this getServerSideProps shall not work. See https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features
To use SSR with AWS amplify see https://docs.aws.amazon.com/amplify/latest/userguide/server-side-rendering-amplify.html#redeploy-ssg-to-ssr or consider deploying on a node server that is actually a server that you can start with next start like AWS EC2 or deploy on Vercel.
Otherwise if you use next export have to make do with client side data fetch only with client side updates only and cannot use dynamic server side features of nextjs.
One reason for context.req.headers not having any cookie in it is because CloudFront distribution is not forwarding any cookies.
This “CloudFront Behaviour” can be changed in two ways:
Forward all cookies, OR
Forward specified cookies (i.e. array of cookie names)
To change the behaviour, navigate to CloudFront on AWS console > Distributions > your_distribution > Behaviors Tab.
Then Edit existing or Create new behaviour > Change cookies settings (for example set it to "All")
In Django, I have my login URL set to 'api/auth/login'. When given a username and password, it will log that user in. Running 'python manage.py runserver', it will put that URL at 'http://127.0.0.1:8000/api/auth/login'
However, my React project, when running 'yarn start' is at 'http://localhost:3000/' and giving it the extension 'api/auth/login', the url it attempts is 'http://localhost:3000/api/auth/login'.
This does not work, but if I replace the URL extension with 'http://127.0.0.1:8000/api/auth/login', the login works as expected.
How can I have the URLs work with my React app? Or is this not something that necessarily needs to be fixed? I do plan to host this project somewhere and am not yet sure how the URLs will work out..
One option is to set proxy in the package.json.
Second option is to set axois baseURL:
// add in your code before main component definition
// for example in App.js
import axios from "axios";
axios.defaults.baseURL = "http://127.0.0.1:8000";
I'm preferring the second approach. For doing production build it can be easily overwritten with an environment variable.
import axios from "axios";
axios.defaults.baseURL = REACT_APP_SERVER_URL
Remember to set the CORS headers in the Django server (I'm working on tutorial with an example how to do this).
You are hosting react application on another port that's why when you put a request without mentioning host, it gets appended to your current host i.e. 127.0.0.1:3000. I suggest you write "proxy": '127. 0.0.1:8000' in your package.json (refer https://create-react-app.dev/docs/proxying-api-requests-in-development/) and restart your react server or use full url of django server i.e. 127.0.0.1:8000/
You know, web applications needs sessions or cookies to authentication. I trying to build web application with Vue.JS and Flask microframework for example ERP or CRM.
I'm confused. How can I work with sessions? Let's think we have a code like this in the Flask:
import os
from flask import Flask, request, jsonify, abort, session
app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY') or \
'e5ac358c-f0bf-11e5-9e39-d3b532c10a28'
#app.route('/login', methods=['POST'])
def user_login():
user = request.form['user']
session['isLogged'] = True
return jsonify({'status': session['isLogged']})
#app.route('/user-info')
def user_info():
if 'isLogged' in session:
return jsonify({'user': 'ali'})
else:
return jsonify({'error': 'Authentication error'})
and our front-end codes should be like this:
mounted() {
this.checkIsLogged();
},
methods: {
checkIsLogged() {
fetch('http://127.0.0.1:5000/user-info', {
mode: 'no-cors',
method: 'GET',
}).then((resp) => {
return resp;
}).then((obj) => {
if(obj.user) {
this.status = true
}
})
},
login() {
let frmData = new FormData(document.querySelector("#frmLogin"));
fetch('http://127.0.0.1:5000/login', {
mode: 'no-cors',
method: 'POST',
body: frmData,
}).then((resp) => {
return resp;
}).then((obj) => {
this.status = obj.status
})
}
}
Everything is normal until I refresh the page. When I refresh the page, I lose the sessions.
Server-side sessions are important for many reasons. If I use localStore or something like that how could be secure I have no idea.
I need some help who worked on similar projects. You can give me suggestions. Because I never worked similar projects.
Other stuff I've read on this topic:
Single page application with HttpOnly cookie-based authentication and session management
SPA best practices for authentication and session management
I'm still confused to about what can I do.
Session handling is something your SPA doesn't really care much about. The session is between the user-agent (browser) and the server. Your vue application doesn't have much to do with it. That's not to say you can't do something wrong, but usually the issue is not with your front end.
That being said it's tough do give an answer to this question because we don't really know what's wrong. What I can do is give you instructions on how you can diagnose this kind of problem. During this diagnosis you'll figure out where the actual issue is and, at least for me, it usually becomes obvious what I need to do.
Step 1)
Use some low level HTTP tool to check the Server response (personally I use curl or Postman when lazy). Send the login request to the server and take a look at the response headers.
When the login is successful you should have a header "Set-Cookie", usually with a content of a "sessionid" or whatever key you're using for sessions.
If you don't see a "Set-Cookie" one of the following is true:
Your server did not start a session and thus did not send a session cookie to the client
there's a proxy/firewall/anti-ad- or tracking plugin somewhere filtering out Cookies
If you see the Set-Cookie Header continue with Step 2, otherwise check the manual in regards to sessions in your chosen backend technology.
Step 2)
Thankfully most modern browsers have a developer console which allows you to do two things:
1) Check your HTTP request headers, body and response headers and body
2) Take a look at stored cookies
Using the first feature (in Chrome this would be under the "Network" tab in the developer console) diagnose the request and response. To do so you need to have the developer console open while performing the login in your app. Check the response of the login, it should contain the Set-Cookie if the login was successful.
If the cookie is not present your server doesn't send it, probably for security reasons (cross-origin policies).
If it is present, the cookie must now be present in the cookie store. In chrome developer console, go to the "Application" tab, expand Cookies from the left menu and take a look at the hosts for which cookies are present. There should be a cookie present which was set in the step before. If not the browser didn't accept the cookie. This usually happens when your cookie is set for a certain domain or path, which isn't the correct one. In such a case you can try to set the domain and/or path to an empty or the correct value (in case of the path a "/").
If your cookie is present, go to step 3
Step 3)
Remember when I said the app has nothing to do with the session. Every request you send either with ajax or simply entering a valid URL in the browser sends all cookies present for this host in the request headers. That is unless you actively prevent whatever library you're using to do so.
If your request doesn't contain the session cookie one of the following is usually true:
the usage of your http library actively prevents sending of cookies
you're sending a correct request but the cookie-domain/path doesn't match the request host/path and is thus not sent along
your cookie is super shortlived and has already expired
If your cookie is sent correctly then your sessions handling should work unless your server doesn't remember that session or starts a new session regardless of an existing session.
I realise this question is quite old and this extensive answer comes way too late, however someone with similar problems may be able to profit from it.
I found an interesting issue when attempting to login using PhantomJS. I'm at a loss as to why it's actually occurring.
Basically you start up a remote debugger like so:
/usr/local/bin/phantomjs --web-security=no --remote-debugger-port=13379 --remote-debugger-autorun=yes /tmp/test.js
Within the remote debugger:
> location.href = "https://www.mysite.com/login"
> $('input[name="username_or_email"]').val('blah#email.com')
> $('input[name="password"]').val('wrongpassword')
> $('button[type="submit"]').submit()
Doing this in Chrome will give me the correct "wrong password" message after the XHR request, whereas using phantomjs gives me a generic error as no cookie is sent with phantomjs (I examined the headers).
I'm quite confused on why phantomjs doesn't send the cookie with the POST request. Does anyone know how we can get phantomjs to send the cookie with ALL requests as it should? Setting a cookie-file doesn't make any difference either.
Ok, this seems to be something related with session cookies and not regular cookies.
Heres a huge thread on the developer in charge of the cookies feature of phantomjs and some guys with the same issue as yours.
https://groups.google.com/forum/#!msg/phantomjs/2UbPkIibnDg/JLV9jBKxhIQJ
If you dont want to skirm through the entire file, basically:
Phantomjs behaves like a regular browser, and it deletes all session cookies when browser closes, in your case, when your script execution ends.
So, even if you set the --cookies-file=/path/to/cookies.txt option you will only store regular cookies on it, for subsecuent executions.
There are two possible approaches for you. One, is to make all requests within the same script, or the other is to store and restore the cookies manually.
On the thread there are a couple of functions that you can use to do this.
function saveCookies(sessionCookieFile, page) {
var fs = require("fs");
fs.write(sessionCookieFile, JSON.stringify(page.cookies));
}
function restoreCookies(sessionCookieFile, page) {
var fs = require("fs");
var cookies = fs.read(sessionCookieFile);
page.cookies = JSON.parse(cookies);
}
var page = require('webpage').create();
And, if everything fails...
You could download source code and recopile phantomjs
You will need to edit src/cookiejar.cpp and remove or comment purgeSessionCookies();
Hope, this helps.