Question

I am using SimpleBrowser that is a part of SimpleTest PHP framework.

The idea is to imitate user interactions with the website and record returned HTML code into a file for further comparison. But something goes wrong here as empty HTML is sometimes returned.

getTransportError() returns Nothing fetched

It happens in completely random places and I can't use back() function because most pages are submitted forms.

require_once('simpletest/browser.php');

class TesterBrowser extends SimpleBrowser
{

    /**
     * Test the page against the reference. If reference is missing, is it created
     * Uses md5 checksum to check if files are identical
     * 
     * @param string $forcename Optional. Substitude autogenerated filename. 
     * @param boolean $forceRef Optional. Force file to be saved as the reference
     *
     * @access public
     *
     * @return void
     */
    public function testPage($forcename = "")
    {
        //who called me?
        //$callers=debug_backtrace();
        //$whocalledme = $callers[1]['function'];
        //get the current source
        $html = $this->getContent();
        //generate filename
        $filename = empty($forcename) ? preg_replace('/[^\w\-'. ''. ']+/u', '-', $this->getUrl()) : $forcename;
        $filename .= ".html";
        //is there a gauge?
        if(file_exists("ref/".$filename) && filesize(dirname(__FILE__)."/ref/".$filename) > 0)
        {
            //is there a difference
            file_put_contents(dirname(__FILE__)."/actual/".$filename, $html);
            if(filesize(dirname(__FILE__)."/actual/".$filename) == 0)
            {
                return false;
            }   
            if(md5_file(dirname(__FILE__)."/actual/".$filename) != md5_file(dirname(__FILE__)."/ref/".$filename))
            {
                echo $this->getUrl() . " (" . $filename . ") has changed \r\n";
            }
        }
        else
        {
            file_put_contents(dirname(__FILE__)."/ref/".$filename, $html);
            if(filesize(dirname(__FILE__)."/ref/".$filename) == 0)
            {
                return false;
            }   
        }
        return true;
    }

    /**
     * Output the string to the terminal
     * 
     * @param mixed $string String to output
     *
     * @access public
     *
     * @return void
     */
    public function output($string)
    {
        echo date("d-m-Y H:i:s") . " - $string... \r\n";
        //update date so that it will be the same on every page
        exec('date -s "24 JUN 2013 10:00:00"');
    }

    /**
     * Restore the server date using external NTP server
     * 
     * @access public
     *
     * @return void
     */
    public function restoreDate(){
        $this->output("Restoring the date&time from NTP server");
        exec("ntpdate 0.uk.pool.ntp.org");
        exec("hwclock -systohc");
    }

}

And the way tests are performed:

class Tester
{
    public $browser = null;
    const BASEURL = "http://ticketing/";

    function __construct(){
        $this->browser = new TesterBrowser();
        $this->browser->setConnectionTimeout(180);

        //get the list of class method to be run
        $methods = array();

        foreach(get_class_methods($this) as $var)
        {
            if(0 === strpos($var, 'test')) //they all start with test
            {
                $methods[] = $var;
            }
        }

        $methods[] = "cleanUp";

        //now we need to run these methods
        foreach($methods as $m){
            while($this->$m() == false){
                $this->browser->output("Empty page, trying again");
                sleep(5);
            }
        }
    }

    //index page
    function testGetIndexPage()
    {
        $this->browser->output("Getting index page");
        $this->browser->get(self::BASEURL);
        return $this->browser->testPage();
    }

    //try to enter wrong password
    function testWrongPassword()
    {
        $this->browser->output("Entering wrong credentials");
        $this->browser->setField("username", "wrong");
        $this->browser->setField("password", "wrong");
        $this->browser->clickSubmitByName("submit");
        return $this->browser->testPage("wrong-credentials");           
    }
        //Delete ticket though admin
    function testDeleteTicketThroughAdmin()
    {
        $this->browser->output("Deleting the ticket through admin page");
        $this->browser->setField("bulk[]", "375341");
        $this->browser->setField("bulkaction", "delete");
        $this->browser->clickSubmit("Do Action");
        return $this->browser->testPage("deleted-ticket-admin");        
    }

    //Restore the date
    function cleanUp()
    {
        $this->browser->restoreDate();
        return true;
    }

}

$tester = new Tester();

There are of course much more test performed and this is a stripped version. I have googled a lot about this problem, there seems to be no adequate documentation whatsoever.

Was it helpful?

Solution

Solved. It was a timeout issue although for some reason no adequate error message is implemented.

$this->browser->setConnectionTimeout(180);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top