Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to click on selectbox options using PhantomJS

There is the page testkrok.org.ua with a consistent selection of parameters. So, I need to create a series of 5 clicks on each of the options of 5 select boxes that depend on each other.

document.querySelector('select.se1')[3]
document.querySelector('select.se2')[1]
document.querySelector('select.se3')[1]
document.querySelector('select.se4')[1]
document.querySelector('select.se5')[3]

to redirect to the page with tests.

But on snapshot taken after the first click the second panel does not appear? Maybe I don't hit the the element?

var page = require('webpage').create();
page.open('https://testkrok.org.ua', function(status) {
    console.log("Status: " + status);
    if(status === "success") {
        page.evaluate(function() {
            var theEvent = document.createEvent("MouseEvent");
            theEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
            var element = document.querySelector('select.se1')[3];
            element.dispatchEvent(theEvent);
        });
    }
    setTimeout( function() {
        page.render('snapshot.png');
        phantom.exit()
    }, 5000);
});
like image 474
khex Avatar asked Sep 24 '15 21:09

khex


1 Answers

You can't click (trigger a click event) on options of a select box. You need to change the selected option and then trigger a change event. For example:

var sel = document.querySelector('select.se1');
sel.selectedIndex = 2;
var event = new UIEvent("change", {
    "view": window,
    "bubbles": true,
    "cancelable": true
});
sel.dispatchEvent(event);

You can package that in a function

function selectOption(selector, optionIndex) {
    page.evaluate(function(selector, optionIndex){
        var sel = document.querySelector(selector);
        sel.selectedIndex = optionIndex;
        var event = new UIEvent("change", {
            "view": window,
            "bubbles": true,
            "cancelable": true
        });
        sel.dispatchEvent(event);
    }, selector, optionIndex);
}

Then you can call it one after the other

selectOption("select.se1", 2);
selectOption("select.se2", 0);
selectOption("select.se3", 0);
...

You get the idea. In case the onChange event of the select box needs remote data for example through AJAX, then you will need to wait between the calls. Either use a static wait time (see following example) or use waitFor().

setTimeout(function(){
    selectOption("select.se1", 2);
}, 1000);
setTimeout(function(){
    selectOption("select.se2", 0);
}, 2000);
setTimeout(function(){
    selectOption("select.se3", 0);
}, 3000);
...
like image 167
Artjom B. Avatar answered Oct 13 '22 13:10

Artjom B.