reCAPTCHA: why can't I check the same result twice? - captcha

I mean if I check first clients input and it is OK the second check of the same input is always false...
Why is that?
I really need ability to check it twice (one for client side validation and second for server side validation)
Thanks in advance!!!
EDIT
Clarifying:
If user's input is ok and recaptcha returns true (I do it through ajax to my server which sends request to recaptcha's server) the form is submitting and sends via POST also 2 variables: recaptcha_challenge_field value and recaptcha_response_field value (which was already checked) and than my server asks recaptcha's server to check again this two values to do server side validation.
Jquery code:
$("#form_id").find("button").click(function(){
var c = $("#recaptcha_challenge_field").val(),
r = $("#recaptcha_response_field").val();
$.ajax({
url: "/ajax/captcha?challenge=" + c + "&response=" + r,
dataType: "json",
success: function(data){
if(data['is_valid']){
$.ajax({
url: "/ajax/captcha?challenge=" + c + "&response=" + r,
dataType: "json",
success: function(data){
if(data['is_valid']){
alert('OK');
}else{
alert('FAILED');
}
}
});
}else{
Recaptcha.reload();
}
}
});
return false;
});
So, as you can see there are two absolutely identical operations with different result (it alerts only FAILED).

Because it is stored in a session that is cleared when the result is submitted. On page load, a new session variable for that CAPTCHA value is generated.

For validating Captcha twice via AJAX/Jquery and on a server page, this is my technique with PHP (the basic idea is just to restore Captcha's Session Variables cleared by the Captcha Check method if correct captcha entered on client side validation, so they will be there again for server side validation):
The following may look confusing as it is one of my lazy way of reusing the client side validation on both the HTML form and the HTML form's action page.
On the HTML form, add an additional POST variable (e.g. $_POST["task"] = "validate" which is not an input element in the form which will be passed on form submission to the client side validation PHP page
$.ajax({
type: "POST",
url: "registration_validate.php",
data: ({
task:"validate" << and other data >>
On the client side validation PHP page
$securimage_session_cv = $_SESSION["securimage_code_value"]["default"];
$securimage_session_ct = $_SESSION["securimage_code_ctime"]["default"];
if ($securimage->check($_POST['captcha_code']) == false) {
// return false or print something
} else {
// if this script is called via ajax for form validation
if(isset($_POST['task']) && trim($_POST['task']) == "validate"){
// captcha will be cleared if valid/correct, restore them as it will be validated again on server side script
$_SESSION["securimage_code_value"]["default"] = $securimage_session_cv;
$_SESSION["securimage_code_ctime"]["default"] = $securimage_session_ct;
}
}
On the server side validation page or form action url, you will have the Captcha Session intact for validation.

Related

get request url after AJAX request

I have a search page with link Search?params but any subsequent search requests are made via Ajax forms using Asp.Net. It makes a request to an action with a different name like InstantSearch?params but in the browser I see Search?params.
From this page I have a link to another page and I need to save the Url to return back to this page.
But if I had an AJAX request, Request.Url returns InstantSearch?params, not the link from browser address bar. And the action from this link returns only a Partial View, so when it returns to the previous URL the page is messed up.
How do I get the link of the previous page, from the browser address bar in Asp.Net, not the actual last requested URL?
While searching we are loading masonry containers like this:
$("#main-content-container").load("/Kit/InstantSearch?" + parameters, function() {
$('#mason-container').imagesLoaded(function() {
$('#mason-container').masonry({
itemSelector: '.kit-thumb-container',
columnWidth: 210,
isFitWidth: true,
gutter: 10
});
});
});
Then I'm calling foundation Joyride on same page and need to pass current page URL to return back. Joyride calls onload of the page under this link:
#Html.ActionLink("Go to kit details help", "OrderPageHelp", "Kit", new { returnUrl = Request.Url }, new { #style = "font-size:16px;" })
The needed page return Url is Kit/Search?params, but Request.Url returns that last request when loading masonry with Kit/InstantSearch?params.
How can I pass the needed Url without hard-coding it?
So this ones a bit old but I found myself in a similar situation recently and found a quick work around. Posting it in case any one's interested.
You can solve this problem by taking advantage of the TempData class.
Temp Data can be used to store data in between requests. The information will remain as long as the session is active, until you retrieve the data again.
So when the user first loads the page, before the ajax method is triggered, store the data in a variable on the page AND in the TempData("YourVariableName") object. Create the Action Link with the Saved URL. When the ajax request is fired it will overwrite the value in Request.URL. So, Check for a value in the TempData("YourVariableName"), if it is there, use that value AND Reset the TempData("YourVariableName") value. This will keep the original value of the page URL even after many ajax requests have been triggered. Code in Visual Basic:
#Code
Dim LastURL As String = ""
If Not TempData("LastURL") Is Nothing Then
LastURL = TempData("LastURL")
TempData("LastURL") = LastURL
Else
LastURL = Request.Url.AbsoluteUri
TempData("LastURL") = LastURL
End If
End Code
And pass the value stored in the LastURL variable as a parameter to your action link.

How do you poll for a condition in Intern / Leadfoot (not browser / client side)?

I'm trying to verify that an account was created successfully, but after clicking the submit button, I need to wait until the next page has loaded and verify that the user ended up at the correct URL.
I'm using pollUntil to check the URL client side, but that results in Detected a page unload event; script execution does not work across page loads. in Safari at least. I can add a sleep, but I was wondering if there is a better way.
Questions:
How can you poll on something like this.remote.getCurrentUrl()? Basically I want to do something like this.remote.waitForCurrentUrlToEqual(...), but I'm also curious how to poll on anything from Selenium commands vs using pollUntil which executes code in the remote browser.
I'm checking to see if the user ended up at a protected URL after logging in here. Is there a better way to check this besides polling?
Best practices: do I need to make an assertion with Chai or is it even possible when I'm polling and waiting for stuff as my test? For example, in this case, I'm just trying to poll to make sure we ended up at the right URL within 30 seconds and I don't have an explicit assertion. I'm just assuming the test will fail, but it won't say why. If the best practice is to make an assertion here, how would I do it here or any time I'm using wait?
Here's an example of my code:
'create new account': function() {
return this.remote
// Hidden: populate all account details
.findByClassName('nextButton')
.click()
.end()
.then(pollUntil('return location.pathname === "/protected-page" ? true : null', [], 30000));
}
The pollUntil helper works by running an asynchronous script in the browser to check a condition, so it's not going to work across page loads (because the script disappears when a page loads). One way to poll the current remote URL would be to write a poller that would run as part of your functional test, something like (untested):
function pollUrl(remote, targetUrl, timeout) {
return function () {
var dfd = new Deferred();
var endTime = Number(new Date()) + timeout;
(function poll() {
remote.getCurrentUrl().then(function (url) {
if (url === targetUrl) {
dfd.resolve();
}
else if (Number(new Date()) < endTime) {
setTimeout(poll, 500);
}
else {
var error = new Error('timed out; final url is ' + url);
dfd.reject(error);
}
});
})();
return dfd.promise;
}
}
You could call it as:
.then(pollUrl(this.remote, '/protected-page', 30000))
When you're using something like pollUntil, there's no need (or place) to make an assertion. However, with your own polling function you could have it reject its promise with an informative error.

Laravel 3 - Passing variables across multiple views

I have two forms on two different views. I would like to post the form input to the second view, and then back to the first form upon posting the second form.
I have set up a test with a route that looks like this :
Route::get('/test1', function() {
return View::make('test1');
});
Route::post('/test2', function() {
$flash = Input::get();
return View::make('test2')->with('flash', $flash);
});
Route::post('/test1', function() {
return View::make('test1')->with('flash', $flash);
});
I am only able to pass $flash once. I'm misunderstanding why I cannot pass it again. I feel like I have to extract it again?
You need to add a form field in /test2 and resubmit the $flash data in order to pass it to /test1 via POST. It's a new request, the app will lose the $flash var otherwise.
A different approach could be to store $flash in a session with Session::put('flash', $flash); and accessing it in the next request.
The best method is to store your data in session. It will be available across multiple request . Using Input::flash() will only be available until the next request. See the Laravel docs for Input::flash() and Session

How to trigger <enter> in an input in Angular scenario test?

I'm writing tests with Angular Scenario test runner. Within a traditional form, I can enter text into an input, but I need to press enter to execute the query and there is no button to click on. Surely there is some easy way to do this, but I do not know what it is.
input('query').enter('foo bar');
// ... now what?
I tried to simulate a keypress with JQuery, but as this answer indicates JQuery is not loaded in the e2e scenarios scope. So I followed his advice (as well as that of this answer) to simulate the keypress:
element('#search_input').query(function(el, done){
var press = document.createEvent('keypress');
press.which = 13;
press.trigger(evt);
done();
});
But to this Angular replies:
NotSupportedError: DOM Exception 9
Error: The implementation did not support the requested type of object or operation.
Update
I realized that a very easy workaround is to include a hidden submit input in my form:
<input id="search-submit" type="submit" style="display:none;">
Then in the scenario: element('#search-submit').click(); does what is needed.
For a purer solution which doesn't involve modifying the HTML for the sake of testing, #florian-f's answer (as well as this one) provides access to jQuery within the DSL via:
var $ = $window.$;
which can be used there or passed to the callback. However, even with this access when triggering a press of enter I was not able to submit my form in the following manner:
$(selector).trigger($.Event('keypress', { which: 13 }));
This must be another issue all together. But I did find jQuery's submit function to do the trick:
$(#the_form).submit();
You can access to the app (runner in an iframe) instance of jQuery :
angular.scenario.dsl('appElement', function() {
return function(selector, fn) {
return this.addFutureAction('element ' + selector, function($window, $document, done) {
fn.call(this, $window.angular.element(selector));
done();
});
};
});
Then you can call the trigger method of jQuery in your test :
appElement('yourSelector', function(elm) {
elm.trigger('enter');//or keypress
});
There is also another possibility to trigger a key event. While your first approach
element('#search_input').query(function(el, done){
var press = document.createEvent('keypress');
press.which = 13;
press.trigger(evt);
done();
});
will be blocked by angular, this one
element(<selector>).query(function($el, done) {
var event = new CustomEvent('keyup');
event.keyCode = 13;
$el.val(2);
$el.get(0).dispatchEvent(event);
done();
});
will pass and trigger a keyup event on the element specified by the selector (keyCode = 13 = Enter Key). See https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent for further information.

undo drag and drop of item

I have a full functional dynatree, where data gets load via ajax (database source), now i enabled drag and drop functionality for the tree. When an item gets dropped i do an ajax request to update the database so node data gets updated. But i do several checks in php to see if node is allowed to be placed on it's "new location".
How can i restore the original location of the node if php rejects the new location where the node is dropped? A full tree reload is possible, but i want to avoid that, and just restore the specific item.
Ok , i found a correct way to do this. I just do my ajax request to php but set it to an sync (async false), so the dynatree code will wait for the result. Then i implemented a check around the move function of dynatree:
$.ajax({
url: "xxx,
async: false,
success: function(data){
if(data.error == 0){
showModalOk(data.message);
phpres = true;
}else
phpres = false;
}
}
});
if(phpres == true){
sourceNode.move(node, hitMode);
node.expand(true);
}
that way the node only gets moved if it's allowed, so no need to restore the node afterwards