in reply to Re^7: Using Perl to Test a Web App that uses Javascript
in thread Using Perl to Test a Web App that uses Javascript

You test JavaScript by seeing that it compares to some known value? I suppose that is important if you are generating the JavaScript but normally I'm testing that functions perform as expected. My testing usually involves make sure that stuff like the following performs correctly, that other functions meant to twiddle form values do the right thing, etc. The thing *is* an application and I'd normally expect tests to run in the context of the browser.

Thinking further ... this implies two separate modes of testing. One mode for testing the server portion of the application. It would be a normal WWW::Mechanise script, probably after using something like HTTP::Recorder to get the expected interaction down. Another mode would script a client to validate that it executed the application as expected. So maybe the client runs against the server, maybe it runs against a dummy server provided by the test, whatever.

Thanks for the thoughts perrin. I'd previously thought it would be a good idea to give JavaScript abilities to WWW::Mechanize but what is really more appropriate is to take HTML-handling functionality away from WWW::Mechanize so it is only a HTTP thing and then script a browser to do all the other testing.

var validationHandlers = new Array(); function register_validation_handler ( validation_handler ) { // Add `function` to the list of functions that will be called whe +n validating // the page. validationHandlers.push( validation_handler ); return validation_handler; } function validate_form () { /* Global function for validating a form. This examines the valida +tionHandlers * array and produces an aggregate result. If there were failures +then the user * is prompted and the function returns false else it returns true +. * * This function is the only intended interface to the validation +functions here * beyond the register_validation_handler( ... ) function. */ // Get an object to hold everything for us. var overall = new ValidationResult(); // Loop through each installed validation handler and add the indi +vidual result to the // cumulative total. for (var ix = 0; ix < validationHandlers.length; ix++) { // Retrieve each handler in turn. var handler = validationHandlers[ ix ]; // And execute it. var result = handler(); // Maintain an overall failure state if (result.failed) overall.failed = result.failed; // Copy over the focus field if it hasn't been set before if (overall.focus_field == null && result.focus_field != null) overall.focus_field = result.focus_field; // Pass in the bad field failure messages. overall.bad_fields = overall.bad_fields.concat( result.bad_fie +lds ); // And any other errors. overall.errors = overall.errors.concat( result.errors ); } // Validation is now complete. // Generate a 'bad fields' message if there are any. if (overall.bad_fields[0] != null) { if (overall.bad_fields.length > 1) overall.error("Please check the following fields for accur +acy:\n"+ overall.bad_fields.join("\n") ); else overall.error("Please check the " + overall.bad_fields[0] ++ " field for accuracy."); } // Report any and all error messages if (overall.errors[0] != null) alert(overall.errors.join("\n\n")); // Since success is the opposite of failure... negate failure to r +eturn the success value. return ! overall.failed } function ValidationResult () { /* * The ValidationResult constructor. * For normal validation see the function validate_form(). * * Execute ` ... = new ValidationResult(); ` to create a new objec +t. * * By default, validation objects are considered to have passed mu +ster. Your validation * code is expected to signal a failure by logging an error messag +e with error(...) or bad data * with bad_field( ... ). * * The end result can be examined by looking at the failed propert +y. */ // Create a new generic object var result = new Object; // Set all of the properties to their default values. result.failed = false; result.bad_fields = new Array(); result.errors = new Array(); result.exit_immediately = false; result.focus_field = null; // Install methods into the new object. result.bad_field = validation_bad_field_method; result.error = validation_error_method; result.debug = validation_debug_method; result.debug = validation_debug_method; return result; } function validation_bad_field_method ( field_name, message ) { // Mark this field as a failure with a message if ( this.focus_field == null) this.focus_field = field_name; // Do some auto-defaulting. if ( message == null || message == '' ) message = field_name; this.bad_fields.push( message ); this.failed = true; return this; } function validation_error_method ( message ) { // Add 'message' to the list of errors, mark the object as failing + validation this.errors.push( message ); this.failed = true; return this; }; function validation_debug_method () { // Prompt the user with the internal state of the validation objec +t. alert( 'failed:'+this.failed+ "\nbad_fields:"+this.bad_fields.join(",")+ "\nerrors:"+this.errors.join(",")+ "\nexit_immediately:"+this.exit_immediately+ "\nfocus_field:"+this.focus_field); return this; }

Replies are listed 'Best First'.
Re^9: Using Perl to Test a Web App that uses Javascript
by McMahon (Chaplain) on Jun 08, 2004 at 20:41 UTC
    The ability to drive JavaScript input from Perl would begin to make Perl a very attractive competitor to the fiendishly expensive Mercury WinRunner and Rational Robot.

    Add support for easy manipulation of iframes/frames, and you'd put serious pressure on Mercury and Rational.
      The ability to drive JavaScript input from Perl would begin to make Perl a very attractive competitor to the
      And it already exists:

      MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
      I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
      ** The third rule of perl club is a statement of fact: pod is sexy.

      Frames? I think you are still confusing client and server. What is there to test about frames that can't be tested with HTTP::Recorder? That they look good?
        No, I'm talking about test automation frameworks that function by driving the client-- not by driving the server. iframes in particular are difficult to manipulate when attempting to automate the manipulation of client-side code.

        The SAMIE documentation (see link above) is a good source for Perlish information about doing this sort of thing.