A Guide to Automating HttpWatch with PHP

calendarMarch 11, 2011 in Automation , HttpWatch

Stoyan Stefanov, the creator of smush.it, architect of YSlow 2.0 and engineer at Facebook, has written an excellent three part guide to controlling HttpWatch from PHP:

He’s even published a class that wraps the HttpWatch API and makes it easier to use from PHP.

In the rest of this blog post we wanted to follow up on a few points mentioned in Stoyan’s blog posts. These items don’t just apply to PHP. You may find them useful when automating HttpWatch using other languages such as C# or Ruby.

Hiding the IE window

The ‘A better experience in IE’ section of Automating HttpWatch with PHP shows how you can hide the IE browser window during tests by separately creating IE and attaching HttpWatch to it.

It’s also possible to do this using the Container property without having to separately create and attach to IE:

$controller = new COM("HttpWatch.Controller");
$plugin = $controller->IE->New();
$browser = $plugin->Container; // Only works with IE
$browser->Visible = false;

If you do decide to do this in order to stop windows popping up during a test please bear these points in mind:

  1. Orphaned instances of iexplore.exe will be left running in the background if your script ever terminates before calling CloseBrowser.
  2. In IE 8 and earlier, HttpWatch will not record a Render Start event because the hidden IE window does not get updated by Windows. However, the event will be recorded in Firefox 3.5+ and IE 9.
  3. Your performance measurements may not directly match user experience. It’s possible that current or future browsers may avoid certain rendering and processing actions if they detect that the output will not be in a visible window. For that reason, we recommend running tests in visible browser windows on a normal interactive desktop either on a physical machine or VM. Also, viewing a browser test through Remote Desktop is likely to have a significant negative impact on performance as the graphics and text making up the page have to be transferred over the network.

Opening the HttpWatch Plugin Window

It’s often handy to open the HttpWatch window in the browser when you are developing an automation script so that you can check that it is working as expected.

The OpenWindow method allows you to do this and specify whether you want the HttpWatch window docked or undocked. For example, here is the PHP code to open HttpWatch as an embedded window in the browser:

...
// Open docked HttpWatch window in browser
$plugin->OpenWindow(false);
...

Handling Differences Between HttpWatch Basic and Professional Editions

In part 3, Stoyan mentions using try-catch to handle the errors that occur when attempting to access data that is restricted in HttpWatch Basic Edition. While this is a valid approach, there is a risk of hiding other errors that might be occurring that are not due to the restrictions in HttpWatch Basic edition.

There are a couple of properties in the HttpWatch automation interface that help you handle the differences. The first is the IsBasicEdition property on the Controller class.

For example, here’s a high level test in PHP:

$controller = new COM("HttpWatch.Controller");
if ( $controller->IsBasicEdition )
{
    echo "\nThis test requires HttpWatch Professional Edition";
}

At a lower level, you can also check each request to see if it has been restricted using the IsRestrictedURL property:

...
if ( $entry->IsRestrictedURL)
{
    // Goes here in HttpWatch Basic Edition for URLs outside Alexa Top 20
    echo "\nSome of the properties for this request are restricted";
}
else
{
    // Goes here in HttpWatch Basic Edition for URLs in Alexa Top 20
    // or in HttpWatch Professional Edition for any URL
    echo "\nAll the properties of this request are available";
}
...

The Firefox Process Model

calendarFebruary 10, 2009 in Automation , Firefox , HttpWatch

One of the interesting new features in Google’s Chrome browser is the use of one Windows process per site or tab. This helps to enforce the isolation between tabs and prevents a problem in one tab crashing the whole browser.

In comparison, Firefox seems to have a simplistic process model on Windows. It doesn’t matter how many tabs or windows you open, or how many times you start Firefox  – by default you get one instance of firefox.exe:

Firefox Process Model

In Internet Explorer you can create a separate instance of the browser process just by starting another copy of iexplore.exe.

There are advantages to Firefox’s single process model:

  1. It uses less system resources per tab compared to creating multiple Windows processes.
  2. Firefox can use fast in-process data access and syncronization objects when it interacts with the history, cookie and cache data stores.

However, the lack of isolation means that if anything causes a page to crash, you’ll lose all your Firefox tabs and windows. This is mitigated to some degree by Firefox’s ability to restart the browser and reload the set of pages displayed in the previous session.

So what do you do if you are developing an add-on for Firefox or you want to run automated tests in Firefox whilst still using Firefox to browse in the normal way?

In Firefox, multi-process support is provided through the use of profiles. When Firefox is installed, you automatically get one default profile that contains user settings, browsing history, the browser cache and persistent cookies. Additional profiles can be created using the Firefox Profile Manager.

The Profile Manager is built into Firefox and is started by running this command in Start->Run:

firefox -P -no-remote

The -P flag indicates that the Profile Manager should be started and the -no-remote flag indicates that any running instances of Firefox should be ignored. If you run without this flag and you have already started Firefox, the command will simply open a new Firefox window without displaying the Profile Manager.

The Profile Manager has a simple user interface that allows you to create, delete and rename profiles:

You can start Firefox in a non-default profile by using the following command line:

firefox -P <myprofile> -no-remote

For example, if you created a new profile called AutoTest:

You could set up a shortcut like this to start Firefox in the AutoTest profile:

Each profile uses its own copy of the firefox.exe process, as well as its own settings, browser cache, history and peristent cookies. This provides more isolation than you would achieve by running multiple processes in IE. You can even separately enable or disable add-ons like Firebug or HttpWatch in each profile.

Internet Explorer’s cache and persistent cookies are maintained on a per user basis making it difficult to run separate instances with their own storage and settings. With Firefox you simply use different profiles. For example, you could use your default profile for normal browsing and have a separate profile to use for another purpose such as automated testing:

The HttpWatch automation interface in version 6.0 supports the use of profiles with Firefox. The profile name can be passed to the Attach and New methods of the Firefox plugin object. Passing an empty string indicates that you want to use the default profile.

Here’s a modified version of the page load test that we previously featured. It’s written in C# and uses a non-default profile to run the test:

// Set a reference to the HttpWatch COM library
// to start using the HttpWatch namespace
using HttpWatch;                
 
namespace EmptyCacheTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "http://www.httpwatch.com";
            string profileName = "AutoTest";
 
            Controller controller = new Controller(); 
 
            // Create an instance of Firefox in the specified profile
            Plugin plugin = controller.Firefox.New(profileName);                
 
            // Clear out all existing cache entries
            plugin.ClearCache();                
 
            plugin.Record();
            plugin.GotoURL(url);                
 
            // Wait for the page to download
            controller.Wait(plugin, -1);                
 
            plugin.Stop();                
 
            // Find the load time for the first page recorded
            double pageLoadTimeSecs =
                plugin.Log.Pages[0].Entries.Summary.Time;                
 
            System.Console.WriteLine( "The empty cache load time for '" +
                url + "' was " + pageLoadTimeSecs.ToString() + " secs");                
 
            // Uncomment the next line to save the results
            // plugin.Log.Save(@"c:\temp\emptytestcache.hwl");                
 
            plugin.CloseBrowser();
        }
    }
}

Ready to get started? TRY FOR FREE Buy Now