I\'m trying to crawl the sizes for this product:
Link to product
The problem: The sizes are loaded after the color of the product is selected.
In th
The recommended jQuery solution doesn't actually work for me.
casper.evaluate(function() {
$('#select_element_selector').val('value').change();
});
While, the capture()
command shows the select option as selected visually, it doesn't actually trigger the event. Try using this with the waitForText()
command for example; the program will timeout.
casper
.start('http://factfinder.census.gov/faces/tableservices/jsf/pages/productview.xhtml?pid=DEC_00_SF1_DP1&prodType=table')
.waitForText('Add/Remove Geographies', function () {
casper.click('#addRemoveGeo_btn');
})
.waitForText('Select a geographic type:', function () {
casper.evaluate(function () {
$('#summaryLevel').val('050').change();
});
})
.waitForText('Select a state:', function () {
casper.capture('test.png');
})
.run();
What did work for me, was the code provided below (thanks @ArtjomB). How to fill a select element which is not embedded in a form with CasperJS?
casper.selectOptionByValue = function(selector, valueToMatch){
this.evaluate(function(selector, valueToMatch){
var select = document.querySelector(selector),
found = false;
Array.prototype.forEach.call(select.children, function(opt, i){
if (!found && opt.value.indexOf(valueToMatch) !== -1) {
select.selectedIndex = i;
found = true;
}
});
// dispatch change event in case there is some kind of validation
var evt = document.createEvent("UIEvents"); // or "HTMLEvents"
evt.initUIEvent("change", true, true);
select.dispatchEvent(evt);
}, selector, valueToMatch);
};
casper.selectOptionByValue('#summaryLevel', '050');
Although, I think CasperJS should provide native support to select options from a drop-down when they aren't apart of a form (http://docs.casperjs.org/en/latest/modules/index.html). Selenium offers the select
and addSelection
commands (https://seleniumhq.github.io/selenium/docs/api/javascript/index.html). I've also filed a pending issue ticket on the CasperJS GitHub page to implement this natively (https://github.com/n1k0/casperjs/issues/1390).
vanilla javascript solution (triggering onchange method):
casper.evaluate(function() {
var select_element = document.getElementById('select_element_selector');
select_element.value = 'value';
select_element.onchange();
});
tejesh95's solution worked for me with a few minor changes, #1 I couldn't get findElementById to work so switched it to 'document.querySelector('#selectorId)' . I also had to change 'onchange' to 'onclick'. Here's the code within the casperjs test harness:
casper.then(function() {
this.evaluate(function() {
var select_element = document.querySelector('#selectorId')
select_element.value = 'stringValue'
select_element.onclick
})
})
Follow on note: Your mileage may vary on the above, I found inconsistent results elsewhere, the text value would update, but the underlying control wouldn't fire. Frustrating!
this is simple code to enter credit card details in casper js
casper.evaluate(function(CC,security_code) {
document.querySelector('input#receipt_creditcard_number').value = CC;
document.querySelector('select#receipt_creditcard_month').selectedIndex = 10;
document.querySelector('select#receipt_creditcard_year').selectedIndex = 10;
document.querySelector('input#receipt_creditcard_verification_value').value = security_code;
document.querySelector('input#receipt_save_creditcard_in_profile').click();
}, '4242424242424242','123');
I don't know if you found a solution to your problem, but here is how I would solve it:
casper.click('#color');
casper.then(function() {
casper.waitFor(function check() {
return this.evaluate(function() {
return document.querySelector('select.select-category').selectedIndex === 2;
});
}, function then() {
/* do the rest that you would want to do!*/
});
}
A slightly hacky way to do this without using jQuery utilising built-in casper methods is:
// Assumes the select box is on the first item at index 0
chooseSelectOption = (friendlyName : string, selectLocator : string, optionIndex : number) => {
casper.test.assertExists(selectLocator, "then select index " + optionIndex + " in the " + friendlyName + " select box");
casper.click(selectLocator);
this.goDown(selectLocator, optionIndex);
};
// recursive funtion to go down various levels
private goDown = (locator: string, depth : number, currentLevel : number = 0) => {
if (currentLevel >= depth) { return; }
casper.sendKeys(locator, casper.page.event.key.Down, { keepFocus: true });
this.goDown(locator, depth, currentLevel + 1);
};
This is in TypeScript but you can edit for vanilla JS if you need to. You need to use a recursive function because a normal for loop gets into difficulties with capser's queuing system.