I'm trying to test a web page that has basic authentication.
This is what I have so far:
var casper = require('casper').create({
verbose: true,
logLevel: 'debug'
});
casper.options.viewportSize = {width: 1366, height: 667};
casper.start();
casper.open( 'http://internal/page.php', {
method: 'get',
headers: {
'Authorization': 'Basic '+btoa('username:password')
}
}).then(function(response) {
this.fill('form[action="page2.php"]', {
cattype: 'BLAH2',
needdate: '04/21/2014'
}, true);
});
casper.then(function() {
this.capture('screenshot-form-entry.png');
});
casper.run(function() {
this.exit();
});
The page opens properly (no authentication problem).
The form fields are set properly.
The problem is the form submission.
It says status=fail.
I look at the server logs and it gives a 401.
Why are the credentials not passed along to the form submission?
Or maybe the question should be, how can a I get the credentials passed along?
After a couple of days of digging I'll answer my own question with what I found.
I'm not sure if this is a bug or the way it's supposed to work.
For basic authorization, you have to set username/password in the pageSettings.
Here is the changed code.
var casper = require('casper').create({
verbose: true,
logLevel: 'debug',
pageSettings: {
userName: 'uid',
password: 'pwd'
}
});
casper.start();
casper.open( 'http://internal/page.php').then(function(response) {
this.fill('form[action="page2.php"]', {
cattype: 'BLAH2',
needdate: '04/21/2014'
}, true);
});
casper.then(function() {
this.capture('screenshot-form-entry.png');
});
casper.run(function() {
this.exit();
});
Related
after hook doesnt work for the first time in cypress but when i retry, it works. in the after hook i call a cy.request and i get a token from another request . i run the token request in before all the tests to make sure i got the token here is the code in the main tests
describe('test', () => {
before(() => {
Login.userLg();
});
it('first test', () => {
cy.visit('`url`);
// some code to test
});
// delete user
afterEach(() => {
user.delete();
});
});
here is the code of the user function in another file (tokenFile)
delete() {
failOnStatusCode: false
cy.request({
method: 'PATCH',
url: `url`,
headers: {
Authorization: 'Bearer ' + Cypress.env('token'),
},
body: {
name: user,
},
});
}
here is the code to get the token in a third file
describe('token', () => {
it('get operator token', () => {
cy.request({
method: 'POST',
url: 'url',
form: true,
body: {
grant_type: 'password',
username: 'user',
password: 'pass',
},
}).then((response) => {
Cypress.env('token', response.body.token);
});
});
});
i call the token request in support/e2e.ts
import './tokenFile';
i tried to put the fucntion in after hook ,put in before hook before login , also i tried afterEach and it didn'T work , i tried to put the token request in command file . nothing works
You should really clear state before tests run rather than after. This is in the official Cypress docs:
https://docs.cypress.io/guides/references/best-practices#Using-after-or-afterEach-hooks
One other benefit of doing this is that if you have a test failure you preserve all the data that the test failed with meaning you can debug the issue.
According to the documentation server configuration for load should return a file object with header Content-Disposition, but what does file object means? How does it looks like?
With my code below I can load the image name correctly only, I need to load preview image and file size also.
Javascript
<script>
FilePond.registerPlugin(FilePondPluginFileValidateType);
FilePond.registerPlugin(FilePondPluginFileValidateSize);
FilePond.registerPlugin(FilePondPluginImagePreview);
FilePond.registerPlugin(FilePondPluginFilePoster);
FilePond.setOptions({
server: {
process: '/upload',
revert: '/remove',
load: '/load/?serverId=',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}
}
});
const inputElement = document.querySelector('#filepond');
const pond = FilePond.create(inputElement, {
files: [
#foreach ($productItem->galleries as $gallery)
{
source: '{{ $gallery->id }}',
options: {
type: 'local',
}
},
#endforeach
],
acceptedFileTypes: ['image/*'],
maxFileSize: '5MB',
onremovefile: (error, file) => {
if (error) {
console.log('Oh no');
return;
}
console.log('File removed', file.getMetadata('serverId'));
}
})
</script>
PHP
public function load(Request $request) {
$file = FileItem::find($request->serverId);
return response()
->json($file->path, 200, [
'Content-Disposition' => "inline; filename='$file->filename'",
]);
}
I see you are using Laravel, instead of handling filepond from scratch. I recommend you to use https://github.com/rahulhaque/laravel-filepond
Easy to use, and if you want to load an initial image or file. you just need a little customization. here is how I handle it.
FilePond.registerPlugin(
FilePondPluginFileValidateType,
FilePondPluginImagePreview,
);
// this is the url of image.
let url = `{{ $slider->getFirstMedia('sliders')->getUrl() }}`;
FilePond.setOptions({
server: {
url: "{{ config('filepond.server.url') }}",
headers: {
'X-CSRF-TOKEN': "{{ #csrf_token() }}",
},
load: (source, load, error, progress, abort, headers) => {
// now load it using XMLHttpRequest as a blob then load it.
let request = new XMLHttpRequest();
request.open('GET', source);
request.responseType = "blob";
request.onreadystatechange = () => request.readyState === 4 && load(request.response);
request.send();
},
}
});
// don't forget to set options local to tell filepond this is already uploaded
// parameter sourse ask for url.
FilePond.create(document.querySelector('#cover'), {
acceptedFileTypes: ['image/png', 'image/jpeg'],
files: [{
source: url,
options: {type: 'local'},
}],
});
Filepond
I'm making an ajax request to retrieve json data from webtrends - a service that requires a login. I'm passing the username and password in my ajax request, but still gives me a 401 unauthorized error. I've tried 3 different methods - but no luck. Can someone pls help me find a solution?
1. $.getJSON('https://ws.webtrends.com/..?jsoncallback=?', { format: 'jsonp', suppress_error_codes: 'true', username: 'xxx', password: 'xxx', cache: 'false' }, function(json) {
console.log(json);
alert(json);
});
2. $.ajax({
url: "https://ws.webtrends.com/../?callback=?",
type: 'GET',
cache: false,
dataType: 'jsonp',
processData: false,
data: 'get=login',
username: "xxx",
password: "xxx",
beforeSend: function (req) {
req.setRequestHeader('Authorization', "xxx:xxx");
},
success: function (response) {
alert("success");
},
error: function(error) {
alert("error");
}
});
3. window.onload=function() {
var url = "https://ws.webtrends.com/...?username=xxx&password=xxx&callback=?";
var script = document.createElement('script');
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);
}
function parseRequest(response) {
try {
alert(response);
}
catch(an_exception) {
alert('error');
}
}
Method 3 might work when you use a named callback function and use basic authentication in the url. Mind though that a lot of browsers don't accept url-authentication (or whatever the name is). If you want to try it, you can rewrite it like this:
window.onload = function() {
var url = "https://xxx:xxx#ws.webtrends.com/...?callback=parseRequest";
var script = document.createElement('script');
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);
}
function parseRequest(response) {
try {
alert(response);
}
catch(an_exception) {
alert('error');
}
}
I have this simple Ajax code, my question is only, what does data.logged return, and what i need to have in the logged.php file...
I'm new to ajax, sorry for the dumb question...
$.ajax('logged.php', {
data: {
login: login,
pass: pass
},
success: function(data)
{
if (data.logged)
{
setTimeout(function() {
document.location.href = 'index.php'
}, 2000);
}
else
{
setTimeout(function() {
formLogin.clearMessages();
displayError('Utilizador ou password errados');
}, 2000);
}
},
error: function()
{
formLogin.clearMessages();
displayError('Error while contacting server, please try again');
}
});
On the client side, adding dataType : 'json' worked for me.
$.ajax('handler.php', {
data: {
login: login,
pass: pass
},
dataType : 'json',
success: function(data)
{
//code here
}
//more code here
}
And then on the server side:
$user = $_GET['login'];
$pass = $_GET['pass'];
$result = array();
if( /* login logic here */) {
$result['logged'] = 'true';
} else {
$result['logged'] = false;
}
header('Content-type: application/json');
echo json_encode($result);
That's a jQuery AJAX request which will be expecting responseText in JSON format. In this case, it seems like the JSON returned by your PHP file only needs to have a single property logged which will be either true or false depending on whether or not the login was successful.
We are building an application using Sencha Touch 1.1 and PhoneGap 1.3.0 for deployment to iOS.
Our app makes several AJAX requests to authenticate a user and retrieve data from the server. All of our requests execute correctly with the exception of attempting to authenticate using invalid credentials.
I am using Weinre to debug the app running in the iOS simulator.
In the Network pane the request hangs on "Pending", and in the console I receive the following error:
error occurred: undefined:[unknown lineno]: ReferenceError: Can't find variable: request
this error appears when the timeout value has been reached.
Here's the code for my controller:
Ext.regController('Login', {
login: function(options)
{
var loader = this.application.viewport.query('#loader')[0];
loader.show();
var string = options.user + ":" + options.pass;
var encodedString = Ext.util.Base64.encode(string) + "==";
Ext.Ajax.defaultHeaders = { Authorization: "Basic " + encodedString};
Ext.Ajax.request({
url: 'http://test.com/login.do',
method: 'POST',
timeout: 5000,
scope: this,
callback: function (options, success, response) {
if (success){
buildingStore.load({
callback: function (){
Ext.redirect('Main/loggedIn');
loader.hide();
}
});
Ext.redirect('Main/loggedIn');
}
else {
alert("failed");
console.log(response.status);
loader.hide();
var loginFailure = new Ext.Panel ({
floating: true,
centered: true,
floating: true,
modal: true,
layout: 'fit',
cls: 'loginError',
html: '<h12>Login was unsuccessful.<br>Please try again.</h12>',
});
loginFailure.show();
}
}
});
Ext.Ajax.on({
requesterror: function(conn, response, options, e){
alert("error");
},
requestexception: function(conn, response, options, e){
alert("exception");
}
});
},
});
and a screenshot of Weinre:
Thanks for your help!
Kevin
Upgrading to sencha touch 1.1 fixes this issue. Credit to #kev_additct. Just putting it in an answer rather than a comment where it already is