最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - CasperJS : dropdown list; select an option, code works in browser&slimer but not with phantom - Stack Overf

programmeradmin3浏览0评论

Here my problem : I'm in a specific case where I try to set the option of a select dropdown list. I usually use this.mouse.up() + this.mouse.down() but I can't in this case because this behavior doesn't work on the website with webkit (you can pare the two with google chrome and Firefox).

Here the url : I want to set the field 'ANNEE' to a year, 2008 in my example

My code : (my function changes the HTML and launches the change() event)

//custom function
casper.fillSelect = function(selectSelector, optionText){
    this.evaluate(function(sel,setByText) {
        if ("createEvent" in document) {
            var evt = document.createEvent("HTMLEvents")
                ,x = document.querySelectorAll(sel + ' > option')
                ,l = x.length
                ;
                evt.initEvent("change", false, true);

            for (i=0; i<l; i++){
                if(x[i].textContent.indexOf(setByText) !== -1){
                    console.log(x[i]);
                    console.log(x[i].getAttribute('value'));
                    x[i].setAttribute('selected', true);
                    x[i].parentNode.dispatchEvent(evt);
                }
            }
        }
        else {console.log("error with fillSelect");}
    },selectSelector, optionText);
};

//event
casper.test.on('fail', function(failure) {
    casper.capture('fail.png');
});

/*************************************** Tests *****************************************************/
casper.test.begin('\n********* Compare : ***********', function (test) {
    "use strict";
    casper.start()
    .thenOpen("",function(){
        casper.fillSelect('fieldset.fcNeutre > div.odSelect:nth-of-type(2) > select', '2008');
    })
    .waitForUrl(/2008/, function(){
        this.capture('fail2.png');
        this.test.assertSelectorHasText("h2", "maximales");
        this.test.assertSelectorHasText("h2", "minimales");
        this.test.assertSelectorHasText("h2", "Paris");
        this.test.assertSelectorHasText("h2", "Le soleil");
        this.test.assertSelectorHasText("h2", "La pluie");
        this.test.assertExists("tspan");
        this.test.assertExists("div.marB20");
        this.test.assertNotEquals(this.fetchText("div.marB20 > table > thead > tr > th"), "", "Table first data not empty");
    })
    .run(function() {
            this.testment('--- Done ---\n');
            test.done();
    });
});

And the equivalent to my casper custom function, you can execute it in the browser :

var fillSelect = function(sel,setByText) {
    if ("createEvent" in document) {
        var evt = document.createEvent("HTMLEvents")
            ,x = document.querySelectorAll(sel + ' > option')
            ,l = x.length
            ;
            evt.initEvent("change", false, true);

        for (i=0; i<l; i++){
            if(x[i].textContent.indexOf(setByText) !== -1){
                //console.log(x[i]);
                //console.log(x[i].getAttribute('value'));
                x[i].setAttribute('selected', true);
                x[i].parentNode.dispatchEvent(evt);
            }
        }
    }
    else {console.log("error with fillSelect");}
};

fillSelect('fieldset.fcNeutre > div.odSelect:nth-of-type(2) > select', '2008');

So it works in FF, Google Chrome, with slimerJS, but not with PhantomJS ... help please, if you have another idea to just select one option in this 'ANNEE' field, with casper+phantom, I take !

Could it be a problem of browser patibility?

It's strange because in the same website, sometimes it works with other 'select', identical to this one ...

Here my problem : I'm in a specific case where I try to set the option of a select dropdown list. I usually use this.mouse.up() + this.mouse.down() but I can't in this case because this behavior doesn't work on the website with webkit (you can pare the two with google chrome and Firefox).

Here the url : I want to set the field 'ANNEE' to a year, 2008 in my example

My code : (my function changes the HTML and launches the change() event)

//custom function
casper.fillSelect = function(selectSelector, optionText){
    this.evaluate(function(sel,setByText) {
        if ("createEvent" in document) {
            var evt = document.createEvent("HTMLEvents")
                ,x = document.querySelectorAll(sel + ' > option')
                ,l = x.length
                ;
                evt.initEvent("change", false, true);

            for (i=0; i<l; i++){
                if(x[i].textContent.indexOf(setByText) !== -1){
                    console.log(x[i]);
                    console.log(x[i].getAttribute('value'));
                    x[i].setAttribute('selected', true);
                    x[i].parentNode.dispatchEvent(evt);
                }
            }
        }
        else {console.log("error with fillSelect");}
    },selectSelector, optionText);
};

//event
casper.test.on('fail', function(failure) {
    casper.capture('fail.png');
});

/*************************************** Tests *****************************************************/
casper.test.begin('\n********* Compare : ***********', function (test) {
    "use strict";
    casper.start()
    .thenOpen("http://www.linternaute./voyage/climat/paris/ville-75056",function(){
        casper.fillSelect('fieldset.fcNeutre > div.odSelect:nth-of-type(2) > select', '2008');
    })
    .waitForUrl(/2008/, function(){
        this.capture('fail2.png');
        this.test.assertSelectorHasText("h2", "maximales");
        this.test.assertSelectorHasText("h2", "minimales");
        this.test.assertSelectorHasText("h2", "Paris");
        this.test.assertSelectorHasText("h2", "Le soleil");
        this.test.assertSelectorHasText("h2", "La pluie");
        this.test.assertExists("tspan");
        this.test.assertExists("div.marB20");
        this.test.assertNotEquals(this.fetchText("div.marB20 > table > thead > tr > th"), "", "Table first data not empty");
    })
    .run(function() {
            this.test.ment('--- Done ---\n');
            test.done();
    });
});

And the equivalent to my casper custom function, you can execute it in the browser :

var fillSelect = function(sel,setByText) {
    if ("createEvent" in document) {
        var evt = document.createEvent("HTMLEvents")
            ,x = document.querySelectorAll(sel + ' > option')
            ,l = x.length
            ;
            evt.initEvent("change", false, true);

        for (i=0; i<l; i++){
            if(x[i].textContent.indexOf(setByText) !== -1){
                //console.log(x[i]);
                //console.log(x[i].getAttribute('value'));
                x[i].setAttribute('selected', true);
                x[i].parentNode.dispatchEvent(evt);
            }
        }
    }
    else {console.log("error with fillSelect");}
};

fillSelect('fieldset.fcNeutre > div.odSelect:nth-of-type(2) > select', '2008');

So it works in FF, Google Chrome, with slimerJS, but not with PhantomJS ... help please, if you have another idea to just select one option in this 'ANNEE' field, with casper+phantom, I take !

Could it be a problem of browser patibility?

It's strange because in the same website, sometimes it works with other 'select', identical to this one ...

Share Improve this question edited Mar 29, 2016 at 19:20 Artjom B. 62k26 gold badges135 silver badges230 bronze badges asked May 14, 2014 at 9:39 FanchFanch 3,2743 gold badges22 silver badges51 bronze badges 1
  • Just a note again; please don't edit your answer into the question. – Andrew Barber Commented May 21, 2014 at 15:32
Add a ment  | 

2 Answers 2

Reset to default 3

So my final solution (thanks to sudipto)

casper.fillSelect = function(selectSelector, optionText){
    this.evaluate(function(sel, val) {
        jQuery(sel).find("option:contains('" + val + "')").attr('selected', true).change();  
    }, selectSelector, optionText);
};

casper.fillSelect('fieldset.fcNeutre > div.odSelect:nth-of-type(2) > select', '2008');

Since the page already has jQuery in it, I wrote this code and the capture as well as currentUrl shows the change happening. Jquery is able to raise the event correctly. I guess.

I hope you can extract the necessary code from this:

casper.on("load.finished", function (status) {
    if (status !== "success") {
        console.log('Failed to load page.');
    }
    else {

        var thisurl = casper.getCurrentUrl();
        window.count = (window.count || 0)+1;
        casper.capture('loaded'+window.count+'.png');

        if (window.count ==1) {
            casper.evaluate(function(sel, val){

                jQuery(sel).find("option:contains('"+val+"')").attr('selected', true);  
                jQuery(sel).change();

            }, 'fieldset.fcNeutre > div.odSelect:nth-of-type(2) > select', 2008);
        }

        console.log('Page loaded.' + thisurl);
        //casper.wait(2000, function(){
    }
});

Best of luck.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论