http://qs321.pair.com?node_id=439001

ForgotPasswordAgain has asked for the wisdom of the Perl Monks concerning the following question:

I work on a large web application which needs lots of UI tests. It uses javascript in places. I started out by subclassing WWW::Mechanize and just emulating the javascript parts, but it gets annoying after a while, not to mention I'd like something more general anyway. So a few weeks ago, I set out on a quest for a way to parse javascript in HTML using Perl.

In fact, I've been asking around, so my apologies if you've heard this story already.

At first, I thought about adding javascript support to WWW::Mechanize using JavaScript::SpiderMonkey. It sounds nice in principle, because JS::SM is the javascript interpreter used by Mozilla. However, in fact it's only the raw interpreter, lacking any browser objects (window, document, etc.) or DOM initialization. After looking at several W3 specifications and HTML::TreeBuilder, I decided to pass on trying to implement the DOM myself.

Next, I found Win32::IE::Mechanize. This uses OLE to control Internet Explorer, and it emulates the WWW::Mechanize interface as a bonus. The only problem is it requires Microsoft® Windows®. Actually, I don't mind Windows so much, but Bricolage doesn't run on Windows so I couldn't test it on my laptop at home.

Trying to find an analogous approach on Linux, I thought of using DCOP with Konqueror, or KHTML. But I couldn't find enough documentation to do useful things (get a handle on the DOM, to click on buttons and links, select from dropdown menus, etc.). If anyone has any pointers/guidance along these lines, it would be much appreciated.

Then I thought again of using Mozilla. This time I had found Gtk2::MozEmbed, which is another great Perl module (the Gtk-Perl documentation and mailing list are fantastic). You can actually embed a Mozilla browser inside a Gtk2 application using Perl. However, it lacks support for things I need (get a handle on the DOM, to click on buttons and links, select from dropdown menus, etc.).

Finally, I found Perl XPCOM, which was yet another very promising path. These are Perl bindings to XPCOM, which are kind of the equivalent of OLE for Mozilla. The problem is, I couldn't get it to build, and the project seems dead (xpcom; the mailing list seems to no longer exist). To be honest, I'm not even sure how I'd proceed once I got XPCOM access, since the documentation I find seems to generally be either about creating XPCOM components in whatever language or is so general or abstract that I don't understand its usefulness.

So then.. I was wondering if anyone had found something. Actually, by this point, I'm not sure I even care whether it uses Perl, as long as I can script interaction with a web application.

UPDATE: I found this discussion. The point Perrin makes is interesting. I have to think about it more, though. I'm not sure if creating tests several pages deep into the interface would work well or not.

UPDATE 2: After noticing an update in the "What's New?" section of the plxpcom site, I built plxpcom in Mozilla 1.6 and it seems to work. I would like to find the "community" for this project, because apparently other than doing `cvs update` every day, there isn't much interaction with the person/people maintaining the project. From a discussion at use.perl.org, I know there are at least one or two others interested in the project.

UPDATE 3 (Aug 5, 2005): See Mozilla::DOM

  • Comment on How can I test a javascript-enhanced web application on Linux?

Replies are listed 'Best First'.
Re: How can I test a javascript-enhanced web application on Linux?
by Joost (Canon) on Mar 12, 2005 at 22:58 UTC
    I heard some good stories about crossover office. It runs internet explorer on linux. Apparently, it might be possible to run Win32::IE::Mechanize on it. Haven't tried it, though.

    Another way to go about it, is to install windows and the tests on a virtual PC like vmware, and run the webapp on the native linux system. VMWare works very well, as long as you have enough memory (I'd recommend at least 1 Gb for a linux system with windows XP under vmware).

    Yet another way, is to port Win32::IE::Mechanize to mozilla, and I would be grateful for the person(s) to accomplish the task, but AFAIK mozilla is not as easy to script as Explorer, so it's probably going to take a lot of time.

      I heard some good stories about crossover office. It runs internet explorer on linux. Apparently, it might be possible to run Win32::IE::Mechanize on it. Haven't tried it, though.
      Here is a node How to install Win32::OLE under Linux? which might help. I'm using it to make SOAP service from macros in Excel. While this works, I wouldn't recommend such combination for writing intensive tests of JavaScript web application (it just seems too slow and flaky).

      When writing jsFind I opted to create separate html page with tests (which takes a long time to execute) and run that manually in different browsers. This served me well (and enabled me to test JavaScript in different browsers), but than again I didn't have to check interaction with web application and it's interactive approach.

      I'm very interesed in solution to this particular problem. Please keep us posted about progress.


      2share!2flame...
        Thanks, I think actually I'll try this approach first, adapting your instructions for installing Win32::OLE to Wine. I hadn't even considered being able to run IE under Linux. (It's even a little disappointing to do that..)
Re: How can I test a javascript-enhanced web application on Linux?
by saintmike (Vicar) on Mar 13, 2005 at 03:06 UTC
    At first, I thought about adding javascript support to WWW::Mechanize using JavaScript::SpiderMonkey. It sounds nice in principle, because JS::SM is the javascript interpreter used by Mozilla. However, in fact it's only the raw interpreter, lacking any browser objects (window, document, etc.) or DOM initialization. After looking at several W3 specifications and HTML::TreeBuilder, I decided to pass on trying to implement the DOM myself.
    You are absolutely correct, the DOM is the missing part. And even if it was implemented in some form, it would be a very special DOM, not reflecting all the myriads of browser bugs, which are accepted 'features' now.

    If you really want to test a web application, you need to test it with all the browsers you're supporting.

    There is, however, the benefit of having an automated regression test, even it it's only for a special (maybe limited) DOM implementation. So far, no one has tackled the task to my knowledge.

Re: How can I test a javascript-enhanced web application on Linux?
by pernod (Chaplain) on Mar 13, 2005 at 11:59 UTC

    I have faced the same problems, and found som half-baked solutions that at least takes me part of the way ...

    iOpus (No realtion to iPod, AFAIK) has a scripting-plugin for Internet Explorer (costs 30$, but they provide a 30 day trial download) that lets you record a browsing session. Using these recorded macros (as they call them), you can test a user scenario such as logging on or entering a form. The macros can be called from the command line and return a success value, and can therefore be baked into a Test::More regime. The main drawback is that it is an Internet Invader only solution, and as far as I know, the macros can not be run from other OS'es. From their website it looks like their latest version can be scripted from Perl, but I haven't tried this myself so I don't know if this can help in any way.

    Another possible solution is to use MaxQ, which does something similar to iOpus. This one uses a proxy for recording browsing sessions, though. It will therefore not really capture anything javascript, since this is purely client side. MaxQ is open source, written in Java and browser sessions are scriptet with the Java implementation of Python called Jython.

    But in the end, perrin is of course right in that you have to test all browsers quirks and weaknesses to verify that your scripts works. I don't know any way to automate this yet, so I really hope someone provides you with a solution. In the meantime, take a look at Peter-Paul Koch's website about browser independent javascripting. Best javascript resource I've found to date ...

    Good luck!

    pernod
    --
    Mischief. Mayhem. Soap.

      Last I checked, only the stripped down version cost $30. The "professional" version, which allows scripts of unlimited length, and windows scripting host control, and other useful stuff, was in the hundreds. The different versions of iopus Internet Macros vary widely in functionality and price, so be sure to read the fine print on the feature comparison page. I do think it's worth checking this product out, as it could be very useful in certain situations.
Re: How can I test a javascript-enhanced web application on Linux?
by Realbot (Scribe) on Mar 13, 2005 at 16:33 UTC
    You could take a look at Selenium.
    From its site: "Selenium tests run directly in a browsers, just as real users do. And they run in Internet Explorer, Mozilla and Firefox on Windows, Linux and Macintosh...Selenium uses JavaScript and Iframes to embed a test automation engine in your browser."

      Looks interesting, thanks. They have Ruby and Java drivers for interacting with the web browser. Basically the javascript repeatedly makes requests back to the test server. Maybe I'll look into making a Perl driver if nobody already is. Or at least take ideas from what he's done there.

      I also found a Mozilla-based Web Spider framework. But that only uses javascript.

Re: How can I test a javascript-enhanced web application on Linux?
by hacker (Priest) on Mar 12, 2005 at 22:30 UTC
    As you probably already know... Javascript isn't "parsed" like HTML or XML, it is "executed" or "interpreted" by the Javascript interpreter.

    There's no easy way to parse the functions that people write (rife with badly-coded and often leaky constructs) with Perl. You'll go crazy trying.

    Here's a little snippet that might help though:

    $page =~ s!<(s(?:cript|tyle))[^>]*>.*?</\1>!!gis;