Search code examples
javascriptdom-eventsphantomjscasperjs

Fill an input field that is not of type text and that triggers events in CasperJS


I have to do automated tests on a website and I want to use CasperJS to learn. For proprietary reasons I can not give too much code.

Here is the example of the input that I am trying to fill:

<input data-bind="value: firstname, valueUpdate: ['blur'], css: {valid:(firstname.isValid() )} " title="" class="valid" aria-required="true" id="firstname" name="firstname">

As you can see, this input is not of type text and has no value attribute. Therefore, I can not use the casper.fill() method. Furthermore, if I enter the web page scope using evaluate() and change the input value using document.querySelector, the change will not be permanent as of the events attached to the text change on the input will not be triggered.

Here is my code:

this.waitForSelector('#memberTitle', function then(){
    var testname = 'thisIsNotPermanent';
    this.evaluate(function(testname){
        document.querySelector('#firstname').value = testname;
    }, testname);
});

If I capture the screen right after, I will see my text written in the input box. However, if I wait 500ms and take another capture, the text is gone as, I suppose, the events are triggered or just cleaned because it actually failed to trigger correctly.

The events attached to the input are of Blur, Change and Keypress.

Using CasperJS, how could I go to the lowest level possible to mimic a user using his keyboard and fully use the website's functionalities already in place?

The whole point of those tests are to work with what is in place. The idea is to not have to manually go through the JavaScript of the web site.


Solution

  • That's exactly what the casper.sendKeys(selector, keys) function is for which will send native keypresses and (hopefully) trigger the events on that text element:

    this.waitForSelector('#memberTitle', function then(){
        var testname = 'thisIsNotPermanent';
        this.sendKeys('#firstname', testname);
    }).wait(20, function(){
        this.capture('screenshot.png');
    });
    

    <input> elements without a type attribute default to Text type.