How to fill a form by id of input in Casperjs? - javascript

I am using Casperjs 1.1.0-beta3 and trying to fill a form by an 'id' selector. I have successfully have used "input[name='userID']" but using an 'id' as a selector always fails with an error similar to the below.
CasperError: Errors encountered while filling form: no field matching css selector "#header-my-account-userid" in form; no field matching css selector "#header-my-account-password" in form
Method 1 works fine. Method 2, 3, 4 all fail. I ONLY TRY ONE METHOD AT A TIME AND COMMENT THE OTHERS OUT. I also cut the extra form tags out for this question.
I found this stackoverflow question on the same subject it still doesn't work.
Any ideas?
HTML
<input id="header-my-account-userid" name="userID" class="m-my-account-userid" maxlength="80" autocomplete="off" placeholder="Email or Rewards #" type="text">
<input id="header-my-account-password" name="password" class="m-my-account-password" maxlength="20" autocomplete="off" placeholder="Password" type="password">
<button type="submit" name="submit" id="header-my-account-sign-in" class="analytics-click m-button-default" title="Sign In">Sign In</button>
Casperjs Script
casper.then(function() {
casper.waitForSelector('form[name=directLoginForm]', function() {
// Method 1 Works
this.fillSelectors("form[name=directLoginForm]", {
'input[name=userID]' : username,
'input[name=password]' : password
}, true);
// Method 2 Does not work
this.fillSelectors("form[name=directLoginForm]", {
'input[id="header-my-account-userid"]' : username,
'input[id="header-my-account-password"]' : password
}, true);
// Method 3 Does not work
this.fillSelectors("form[name=directLoginForm]", {
'header-my-account-userid' : username,
'header-my-account-password' : password
}, true);
// Method 4 Does not work
this.fillSelectors("form[name=directLoginForm]", {
'#header-my-account-userid' : username,
'#header-my-account-password' : password
}, true);
});
});

Well i tried, they all work (except 3 because your selector is invalid).
I put the bool to false to see the changes, but you shouldn't have 'Errors encountered while filling form: no field matching css selector "#header-my-account-userid'.
It's not a casper error so, it's specific to your case. It doesn't recognize your id for obscure reasons.
this.sendKeys('input[id="header-my-account-userid"]', username);
sendKeys works also.

Wait for the form to be loaded to fill the form using the selectors.Use have waitForSelector(),waitFor(),wait() etc other than waitForResource()
casper.start('your_url_here',function(){
this.echo(this.getTitle());
});
casper.waitForResource("your_url_here",function() {
this.fillSelectors('#loginform', {
'input[name="Email"]' : 'your_email',
'input[name="Passwd"]': 'your_password'
}, true);
});

A minimal example revealed that only method 3 shouldn't work. I suspect you check for 'working' form by checking if the next page loads. It might be the case that casper doesn't find the submit button. Try explicitly clicking the button.
Additionally, PhantomJS has sometimes a problem with non-quoted attribute selectors. You should change
"form[name=directLoginForm]"
to
"form[name='directLoginForm']"

I find that this happens when casperJS is too fast for the browser and a casper.wait() will solve the issue.
This is an example:
// Make a test order
casper.then(function() {
casper.waitForSelector('#onestepcheckout-form', function() {
this.fillSelectors('#onestepcheckout-form', {
'input[id="billing:telephone"]': '12344534',
'input[id="billing:postcode"]': '432323',
'input[id="billing:city"]': 'London',
'input[id="billing:street1"]': 'Lambada is a good music'
}, false);
})
casper.wait(5000, function() {
this.fillSelectors('#onestepcheckout-form', {
'#sagepaydirectpro_cc_owner': 'Fizipit o Moyazoci',
'input[id="agreement-1"]': true
}, true);
})
this.test.pass('form populated');
});

Related

JQuery and HTML5 custom validation not working as intended

I just started learning JS, Jquery and HTML online. I have a question, and have tried doing things which were told in the answers of similar questions on SO, but it won't help.
I have a password form which only accepts input which have atleast 6 characters, one uppercase letter and one number. I wish to show a custom validation message which could just state these conditions again.
Here's my HTML code -
<div class="password">
<label for="password"> Password </label>
<input type="password" class="passwrdforsignup" name="password" required pattern="(?=.*\d)(?=.*[A-Z]).{6,}"> <!--pw must contain atleast 6 characters, one uppercase and one number-->
</div>
I'm using JS to set the custom validation message.
JS code
$(document).ready(function () {
$('.password').on('keyup', '.passwrdforsignup', function () {
var getPW = $(this).value();
if (getPW.checkValidity() === false) {
getPW.setCustomValidity("This password doesn't match the format specified");
}
});
});
However, the custom validation message doesn't show. Please help. Thank you so much in advance! :)
UPDATE 1
I changed the password pattern to (?=.*\d)(?=.*[A-Z])(.{6,}). Based on 4castle's advise, I realized there were a few errors in my javascript, and changed them accordingly. However, the custom validation message still doesn't show.
JavaScript:
$(document).ready(function () {
$('.password').on('keyup', '.passwrdforsignup', function () {
var getPW = $(this).find('.passwrdforsignup').get();
if (getPW.checkValidity() === false) {
getPW.setCustomValidity("This password doesn't match the format specified");
}
});
});
Again, than you all in advance!
First, update this:
var getPW = $(this).find('.passwrdforsignup').get();
to this:
var getPW = $(this).get(0);
...because $(this) is already the textbox .passwrdforsignup, you can't find it in itself!
The problem with setCustomValidity is, that it does only work once you submit the form. So there is the option to do exactly that:
$(function () {
$('.password').on('keyup', '.passwrdforsignup', function () {
var getPW = $(this).get(0);
getPW.setCustomValidity("");
if (getPW.checkValidity() === false) {
getPW.setCustomValidity("This password doesn't match the format specified");
$('#do_submit').click();
}
});
});
Please note the getPW.setCustomValidity(""); which resets the message which is important because if you do not do this, getPW.checkValidity() will always be false!
For this to work the textbox (and the submit-button) must be in a form.
Working JSFiddle
There are several issues going on here.
The pattern doesn't have a capture group, so technically nothing can ever match it. Change the pattern to (?=.*\d)(?=.*[A-Z])(.{6,})
$(this).value() doesn't refer to the value of the input tag, it's referring to the value of .password which is the container div.
getPW.checkValidity() and getPW.setCustomValidity("blah") are getting run on a string, which doesn't have definitions for those functions, only DOM objects do.
Here is what you should do instead (JS code from this SO answer)
$(document).ready(function() {
$('.passwrdforsignup').on('invalid', function(e) {
var getPW = e.target;
getPW.setCustomValidity("");
if (!getPW.checkValidity())
getPW.setCustomValidity("This password doesn't match the format specified");
}).on('input', function(e) {
$(this).get().setCustomValidity("");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div class="password">
<label for="password">Password</label>
<input type="password" class="passwrdforsignup" name="password"
required pattern="(?=.*\d)(?=.*[A-Z])(.{6,})" />
</div>
<input type="submit" />
</form>

jQuery validation with any inputs before an 'require_from_group_exact' validated input does not validate properly

I am using the jQuery Validation Plugin to validate a number of inputs on a html page. The first name is always required, and either email OR mobile but not both. To do this, I use the require_from_group_exact method.
When the inputs are in this order, validation occurs perfectly:
<form>
Email: <input class="commsinfo" name="email"><br>
Mobile: <input class="commsinfo" name="mobile"><br>
Name: <input name="firstname"><br>
<input type="submit">
</form>
However if you swap the inputs around, validation of the last input (firstname) does not occur properly (you have to type a firstname and then delete it to trigger validation) - why??. This is the desired order and issue I'm trying to solve - is it a bug with the jQuery Validation Plugin or my code?
<form>
Name: <input name="firstname"><br>
Email: <input class="commsinfo" name="email"><br>
Mobile: <input class="commsinfo" name="mobile"><br>
<input type="submit">
</form>
I have created a JSFiddle of the version the does not validate properly. The code for the jQuery.validator.addMethod and $('form').validate can be seen in the fiddle.
You're not checking all the input fields,
change var fields = $(selector, element.form);
to var fields = $('form :input');
Updated Fiddle
In the example you've provided, there seems to be an issue with the call to fields.valid().
I've updated the fiddle to remove some code I don't think you need. The call to valid() seems to be the crux of the problem and removing it causes the validation to work as expected.
The updated code now looks like this:
jQuery.validator.addMethod("require_from_group_exact", function(value, element, options) {
var validator = this;
var selector = options[1];
var validOrNot = $(selector, element.form).filter(function() {
return validator.elementValue(this);
}).length == options[0];
return validOrNot;
}, jQuery.format("Please fill {0} of these fields."));
$('form').validate({
rules: {
firstname: { required: true },
email: { require_from_group_exact: [1, ".commsinfo"] },
mobile: { require_from_group_exact: [1, ".commsinfo"] },
}
});
Updated Fiddle
Every time you call the
fields.valid();
your validator method is recalled and so you get the apparently strange behaviour. You can check this debugging by yourself.

jQuery validation with input mask

Have this problem that form inputs with assigned mask (as a placeholder) are not validated as empty by jQuery validation.
I use:
https://github.com/RobinHerbots/jquery.inputmask
https://github.com/1000hz/bootstrap-validator
(which uses jQuery native validation in this case)
Some strange behaviors:
Inputs with attribute required are validated (by jQuery) as not empty and therefore valid, but in the other hand input is not considered as "not empty" and not checked for other validation rules (this is by validator.js)
When i write something into input field and then erase it, I get required error message
Can anyone give me some hint?
EDIT:
Relevant code:
HTML/PHP:
<form enctype="multipart/form-data" method="post" id="feedback">
<div class="kontakt-form-row form-group">
<div class="kontakt-form">
<label for="phone" class="element">
phone<span class="required">*</span>
</label>
</div>
<div class="kontakt-form">
<div class="element">
<input id="phone" name="phone" ' . (isset($user['phone']) ? 'value="' . $user['phone'] . '"' : '') . ' type="text" maxlength="20" class="form-control" required="required" data-remote="/validator.php">
</div>
</div>
<div class="help-block with-errors"></div>
</div>
</form>
JS:
$(document).ready(function() {
$('#phone').inputmask("+48 999 999 999");
$('#feedback').validator();
});
I managed to use the RobinHerbots's Inputmask (3.3.11), with jQuery Validate, by activating clearIncomplete. See Input mask documentation dedicated section:
Clear the incomplete input on blur
$(document).ready(function(){
$("#date").inputmask("99/99/9999",{ "clearIncomplete": true });
});
Personnaly, when possible, I prefer setting this by HTML data attribute:
data-inputmask-clearincomplete="true"
The drawback is: partial input is erased when focus is lost, but I can live with that. So maybe you too ...
Edit: if you need to add the mask validation to the rest of your jQuery Validate process, you can simulate a jQuery Validate error by doing the following:
// Get jQuery Validate validator currently attached
var validator = $form.data('validator');
// Get inputs violating masks
var $maskedInputList
= $(':input[data-inputmask-mask]:not([data-inputmask-mask=""])');
var $incompleteMaskedInputList
= $maskedInputList.filter(function() {
return !$(this).inputmask("isComplete");
});
if ($incompleteMaskedInputList.length > 0)
{
var errors = {};
$incompleteMaskedInputList.each(function () {
var $input = $(this);
var inputName = $input.prop('name');
errors[inputName]
= localize('IncompleteMaskedInput_Message');
});
// Display each mask violation error as jQuery Validate error
validator.showErrors(errors);
// Cancel submit if any such error
isAllInputmaskValid = false;
}
// jQuery Validate validation
var isAllInputValid = validator.form();
// Cancel submit if any of the two validation process fails
if (!isAllInputValid ||
!isAllInputmaskValid) {
return;
}
// Form submit
$form.submit();
It's not exactly the solution, but...
changing inputmask for some equivalent solves the problem.
Still far from perfect, though : (
EXPLANATION:
Other masking libraries, don't have these two strange behaviors mentioned, so it's possible to validate fields.
I used:
https://github.com/digitalBush/jquery.maskedinput
I have the same issue when combined these two libs together.
Actually there is a similar ticket here: https://github.com/RobinHerbots/Inputmask/issues/1034
Here is the solution provided by RobinHerbots:
$("#inputPhone").inputmask("999.999.9999", {showMaskOnFocus: false, showMaskOnHover: false});
The validator assumes that it is not empty when the mask focus/hover is there.
simply turn focus and hover of the mask off will fix the problem.
I solved this problem with:
phone_number: {
presence: {message: '^ Prosimy o podanie numeru telefonu'},
format: {
pattern: '(\\(?(\\+|00)?48\\)?)?[ -]?\\d{3}[ -]?\\d{3}[ -]?\\d{3}',
message: function (value, attribute, validatorOptions, attributes, globalOptions) {
return validate.format("^ Nieprawidłowa wartość w polu Telefon");
}
},
length: {
minimum: 15,
message: '^ Prosimy o podanie numeru telefonu'
},
},

Adding own rule in jquery validation plugin

I have next jquery code:
$("input").rules("add", {
required: true,
messages: {
required: 'Please enter your telephone number'
},
errorPlacement: function(error, element) {
console.log('bob');
element.insertBefore(error);
}
});
I am trying to add new rule like in answer in this question : jquery validation & id's ft numbers
I have such html code:
<form method='post' action='' id='#countersForm'>
<input id="88" class="counter_input active" type="text" enabled="">
<input id="89" class="counter_input active" type="text" enabled="">
</form>
My problems are:
1) Why browser tries to validate field on page loaded? I don't need this (message bob appeaing on page load.
2) Why only first input field is validating? I want to validate all fields.
3) Why console says , that element is not defined?
documentation says that element parameter contain validated element. console.log(element) says that it is undefiened. Why?
From documentation:
Read, add and remove rules for an element.
it says 'an' element. $('input') in your case returns two elements.
validation plugin uses name attribute of elements, your element's doesn't have names.
You have to initialize the plugin using validate() method on the form you want to validate, for e.g.
$("#myform").validate({ //where my form is the id of your form
rules: {
name: "required", //name is the name of your element
},
messages: {
}
});
Thanks for your answers and comments.
I solved my problem. Working code (current problem is solved) is here: http://jsfiddle.net/2LRv7/2/
There was a huge mistake in my js code. I put errorPlacement section to the rules function. I have to put this option to .validate section.
$("#countersForm").validate({
errorPlacement: function (error, element) {
console.log(error);
var br = $( "<br>" );
error.insertAfter(element);
br.insertAfter(element);
}
});
Also, as #TilwinJoy said, I used $('input').rules(/*....*/) wrong. I had to use each function.
This code is okay:
$("input").each(function () { // next code will affect all input fields
$(this).rules("add", { // $(this) is my input field
required: true,
digits: true,
messages: {
required: 'Это поле обязательно для заполнения',
digits: 'В поле могут быть только цифры'
}
});
});
Current problem solved, but I have another. If you want to help check this question: Class is not being added to the error element on first check , but when field is being checked again all going ok (jquery validation plugin)

jQuery validate plugin on DIV

I am trying to use the validate plugin on a div as shown in the answer to this question:
<script type="text/javascript">
$("#pseudoForm").validate({
onfocusout:true,
rules:{
first_name:"required",
last_name:"required"
}
});
</script>
<!-- whatever -->
<div id="pseudoForm">
<input type="text" name="first_name"/>
<input type="text" name="last_name"/>
</div>
I have all within a form.
I am getting a bunch of different errors on different browsers.
Firefox: validator in undefined
IE8: 'settings' is null or not an
object
Chrome: Cannot read property 'settings' of undefined
Any help appreciated!
This isn't the answer you want to hear, but the other answer is incorrect (it may have been right when it was posted, but there have been several major jQuery validation plugin changes since then).
The validation plugin is (currently) designed to work on a <form>, and only on a <form>. You can also note that all of the plugin documentation references a form, not any other generic container.
The plugin itself keeps track of validator.currentForm internally, which refers to the this of the passed in selector, getting .elements, etc off that...it's really not going to work any other way, not the way the current version's written.
The overall solution/alternative approach here: call .validate() on the <form> element (the jQuery wrapper for it rather) directly, not any other container. If you need to divide your <form> use <fieldset> elements, possibly using the ignore: ':hidden' option in .validate() if you don't want to validate input fields that aren't visible to the user.
You're missing a closing bracket. Try this instead:
$("#pseudoForm").validate({
onfocusout:true,
rules:{
first_name:"required",
last_name:"required"
}
});
You can get the same error if you select the form by class
$(".form_class").validate(...
instead of by ID
$("#form_id").validate(...
or tag name
$("form").validate(...
Open jquery.validate.js or jquery.validate.min.js and find(ctrl + F) "label" and replaceAll with your your required tag:
Example: div
then perform validation.
//HTML
<div class="form-group has-feedback col-xs-8 " style="padding-right:0px">
<input type="tel" class="form-control" name="Otp_MobileNo" id="mobileNo" placeholder="Mobile No." minlength="10" maxlength="10">
<span id="mobileno_message" style="display:none;color: red;">Please enter a valid Mobile No</span>
</div>
//Java Script
$("#getOtp").click(function(){
jQuery(document).ready(function(){
var MobileNo = jQuery("#mobileNo").val();
var MobileNoLength = MobileNo.length;
var zipRegex = /^\d{10}$/;
var mobileNo = $("#mobileNo").val();
if (!zipRegex.test(MobileNo))
{
jQuery('#mobileno_message').show();
}
else
{
// success!
jQuery('#mobileno_message').hide();
$.ajax({
type : 'POST',
url : '<?php echo site_url('Login/send_otp'); ?>',
data : {Otp_MobileNo:mobileNo,},
dataType : 'json',
beforeSend: function()
{
$("#error").fadeOut();
},
success : function(response)
{
alert(response.message_text);
$("#check-otp").delay().animate({
height: 'toggle',
},
"slow");
$("#getOtp").hide();
}
});
}
});
});

Categories

Resources