Move debugger to new api and add basic unit tests for it
authorgggeek <giunta.gaetano@gmail.com>
Sun, 29 Mar 2015 14:35:48 +0000 (15:35 +0100)
committergggeek <giunta.gaetano@gmail.com>
Sun, 29 Mar 2015 14:35:48 +0000 (15:35 +0100)
debugger/action.php
debugger/common.php
debugger/controller.php
debugger/index.html [deleted file]
src/Wrapper.php
tests/5DemofilesTest.php
tests/6DebuggerTest.php [new file with mode: 0644]

index 2e5e4c5..f77c876 100644 (file)
 include __DIR__ . '/common.php';
 if ($action) {
 
+    include_once __DIR__ . "/../src/Autoloader.php";
+    PhpXmlRpc\Autoloader::register();
+
     // make sure the script waits long enough for the call to complete...
     if ($timeout) {
         set_time_limit($timeout + 10);
     }
 
-    include 'xmlrpc.inc';
     if ($wstype == 1) {
         @include 'jsonrpc.inc';
         if (!class_exists('jsonrpc_client')) {
             die('Error: to debug the jsonrpc protocol the jsonrpc.inc file is needed');
         }
-        $clientclass = 'jsonrpc_client';
-        $msgclass = 'jsonrpcmsg';
-        $protoname = 'JSONRPC';
+        $clientClass = 'PhpJsRpc\client';
+        $requestClass = 'PhpJsRpc\request';
+        $protoName = 'JSONRPC';
     } else {
-        $clientclass = 'xmlrpc_client';
-        $msgclass = 'xmlrpcmsg';
-        $protoname = 'XMLRPC';
+        $clientClass = 'PhpXmlRpc\client';
+        $requestClass = 'PhpXmlRpc\Request';
+        $protoName = 'XMLRPC';
     }
 
     if ($port != "") {
-        $client = new $clientclass($path, $host, $port);
+        $client = new $clientClass($path, $host, $port);
         $server = "$host:$port$path";
     } else {
-        $client = new $clientclass($path, $host);
+        $client = new $clientClass($path, $host);
         $server = "$host$path";
     }
     if ($protocol == 2) {
@@ -189,30 +191,24 @@ if ($action) {
 
     $msg = array();
     switch ($action) {
-
-        case 'wrap':
-            @include 'xmlrpc_wrappers.inc';
-            if (!function_exists('build_remote_method_wrapper_code')) {
-                die('Error: to enable creation of method stubs the xmlrpc_wrappers.inc file is needed');
-            }
         // fall thru intentionally
         case 'describe':
         case 'wrap':
-            $msg[0] = new $msgclass('system.methodHelp', array(), $id);
-            $msg[0]->addparam(new xmlrpcval($method));
-            $msg[1] = new $msgclass('system.methodSignature', array(), $id + 1);
-            $msg[1]->addparam(new xmlrpcval($method));
+            $msg[0] = new $requestClass('system.methodHelp', array(), $id);
+            $msg[0]->addparam(new PhpXmlRpc\Value($method));
+            $msg[1] = new $requestClass('system.methodSignature', array(), $id + 1);
+            $msg[1]->addparam(new PhpXmlRpc\Value($method));
             $actionname = 'Description of method "' . $method . '"';
             break;
         case 'list':
-            $msg[0] = new $msgclass('system.listMethods', array(), $id);
+            $msg[0] = new $requestClass('system.listMethods', array(), $id);
             $actionname = 'List of available methods';
             break;
         case 'execute':
             if (!payload_is_safe($payload)) {
                 die("Tsk tsk tsk, please stop it or I will have to call in the cops!");
             }
-            $msg[0] = new $msgclass($method, array(), $id);
+            $msg[0] = new $requestClass($method, array(), $id);
             // hack! build xml payload by hand
             if ($wstype == 1) {
                 $msg[0]->payload = "{\n" .
@@ -256,7 +252,7 @@ if ($action) {
     $time = (float)$mtime[0] + (float)$mtime[1];
     foreach ($msg as $message) {
         // catch errors: for older xmlrpc libs, send does not return by ref
-        @$response = &$client->send($message, $timeout, $httpprotocol);
+        @$response = $client->send($message, $timeout, $httpprotocol);
         $resp[] = $response;
         if (!$response || $response->faultCode()) {
             break;
@@ -272,14 +268,14 @@ if ($action) {
         if ($response->faultCode()) {
             // call failed! echo out error msg!
             //echo '<h2>'.htmlspecialchars($actionname).' on server '.htmlspecialchars($server).'</h2>';
-            echo "<h3>$protoname call FAILED!</h3>\n";
+            echo "<h3>$protoName call FAILED!</h3>\n";
             echo "<p>Fault code: [" . htmlspecialchars($response->faultCode()) .
                 "] Reason: '" . htmlspecialchars($response->faultString()) . "'</p>\n";
             echo(strftime("%d/%b/%Y:%H:%M:%S\n"));
         } else {
             // call succeeded: parse results
             //echo '<h2>'.htmlspecialchars($actionname).' on server '.htmlspecialchars($server).'</h2>';
-            printf("<h3>%s call(s) OK (%.2f secs.)</h3>\n", $protoname, $time);
+            printf("<h3>%s call(s) OK (%.2f secs.)</h3>\n", $protoName, $time);
             echo(strftime("%d/%b/%Y:%H:%M:%S\n"));
 
             switch ($action) {
@@ -324,7 +320,7 @@ if ($action) {
                                 "<input type=\"submit\" value=\"Describe\" /></form></td>");
                             //echo("</tr>\n");
 
-                            // generate lo scheletro per il method payload per eventuali test
+                            // generate the skeleton for method payload per possible tests
                             //$methodpayload="<methodCall>\n<methodName>".$rec->scalarval()."</methodName>\n<params>\n<param><value></value></param>\n</params>\n</methodCall>";
 
                             /*echo ("<form action=\"{$_SERVER['PHP_SELF']}\" method=\"get\"><td>".
@@ -388,7 +384,7 @@ if ($action) {
                                 echo 'Unknown';
                             }
                             echo '</td>';
-                            //bottone per testare questo metodo
+                            // button to test this method
                             //$payload="<methodCall>\n<methodName>$method</methodName>\n<params>\n$payload</params>\n</methodCall>";
                             echo "<td$class><form action=\"controller.php\" target=\"frmcontroller\" method=\"get\">" .
                                 "<input type=\"hidden\" name=\"host\" value=\"" . htmlspecialchars($host) . "\" />" .
@@ -462,7 +458,8 @@ if ($action) {
                         echo "Error: signature unknown\n";
                     } else {
                         $mdesc = $r1->scalarval();
-                        $msig = php_xmlrpc_decode($r2);
+                        $encoder = new PhpXmlRpc\Encoder();
+                        $msig = $encoder->decode($r2);
                         $msig = $msig[$methodsig];
                         $proto = $protocol == 2 ? 'https' : $protocol == 1 ? 'http11' : '';
                         if ($proxy == '' && $username == '' && !$requestcompression && !$responsecompression &&
@@ -478,7 +475,8 @@ if ($action) {
                             $prefix = 'xmlrpc';
                         }
                         //$code = wrap_xmlrpc_method($client, $method, $methodsig, 0, $proto, '', $opts);
-                        $code = build_remote_method_wrapper_code($client, $method, str_replace('.', '_', $prefix . '_' . $method), $msig, $mdesc, $timeout, $proto, $opts, $prefix);
+                        $wrapper = new PhpXmlRpc\Wrapper();
+                        $code = $wrapper->build_remote_method_wrapper_code($client, $method, str_replace('.', '_', $prefix . '_' . $method), $msig, $mdesc, $timeout, $proto, $opts, $prefix);
                         //if ($code)
                         //{
                         echo "<div id=\"phpcode\">\n";
index 642326a..e8ad64c 100644 (file)
@@ -4,6 +4,8 @@
  * @copyright (C) 2005-2015 G. Giunta
  * @license code licensed under the BSD License: see file license.txt
  *
+ * Parses GET/POST variables
+ *
  * @todo switch params for http compression from 0,1,2 to values to be used directly
  * @todo do some more sanitization of received parameters
  */
index d5c8610..6051f92 100644 (file)
@@ -18,8 +18,8 @@ if ($action == '') {
 }
 
 // relative path to the visual xmlrpc editing dialog
-$editorpath = '../../javascript/debugger/';
-$editorlibs = '../../javascript/lib/';
+$editorpath = '../../phpjsrpc/debugger/';
+$editorlibs = '../../phpjsrpc/lib/';
 ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -224,15 +224,12 @@ $editorlibs = '../../javascript/lib/';
         echo ' document.forms[2].submit();';
     } ?>">
 <h1>XMLRPC
-    <form name="frmxmlrpc" style="display: inline;" action="."><input name="yes" type="radio"
-                                                                      onclick="switchtransport(0);"/></form>
+    <form name="frmxmlrpc" style="display: inline;" action="."><input name="yes" type="radio" onclick="switchtransport(0);"/></form>
     /
-    <form name="frmjsonrpc" style="display: inline;" action="."><input name="yes" type="radio"
-                                                                       onclick="switchtransport(1);"/></form>
-    JSONRPC Debugger (based on the <a href="http://phpxmlrpc.sourceforge.net">PHP-XMLRPC</a> library)
+    <form name="frmjsonrpc" style="display: inline;" action="."><input name="yes" type="radio" onclick="switchtransport(1);"/></form>
+    JSONRPC Debugger (based on the <a href="http://gggeek.github.io/phpxmlrpc/">PHP-XMLRPC</a> library)
 </h1>
-<form name="frmaction" method="get" action="action.php" target="frmaction" onSubmit="switchFormMethod();"
-    >
+<form name="frmaction" method="get" action="action.php" target="frmaction" onSubmit="switchFormMethod();">
 
     <table id="serverblock">
         <tr>
@@ -250,19 +247,10 @@ $editorlibs = '../../javascript/lib/';
     <table id="actionblock">
         <tr>
             <td><h2>Action</h2></td>
-            <td>List available methods<input type="radio" name="action" value="list"<?php if ($action == 'list') {
-                    echo ' checked="checked"';
-                } ?> onclick="switchaction();"/></td>
-            <td>Describe method<input type="radio" name="action" value="describe"<?php if ($action == 'describe') {
-                    echo ' checked="checked"';
-                } ?> onclick="switchaction();"/></td>
-            <td>Execute method<input type="radio" name="action" value="execute"<?php if ($action == 'execute') {
-                    echo ' checked="checked"';
-                } ?> onclick="switchaction();"/></td>
-            <td>Generate stub for method call<input type="radio" name="action"
-                                                    value="wrap"<?php if ($action == 'wrap') {
-                    echo ' checked="checked"';
-                } ?> onclick="switchaction();"/></td>
+            <td>List available methods<input type="radio" name="action" value="list"<?php if ($action == 'list') { echo ' checked="checked"'; } ?> onclick="switchaction();"/></td>
+            <td>Describe method<input type="radio" name="action" value="describe"<?php if ($action == 'describe') { echo ' checked="checked"'; } ?> onclick="switchaction();"/></td>
+            <td>Execute method<input type="radio" name="action" value="execute"<?php if ($action == 'execute') { echo ' checked="checked"'; } ?> onclick="switchaction();"/></td>
+            <td>Generate stub for method call<input type="radio" name="action" value="wrap"<?php if ($action == 'wrap') { echo ' checked="checked"'; } ?> onclick="switchaction();"/></td>
         </tr>
     </table>
     <input type="hidden" name="methodsig" value="<?php echo htmlspecialchars($methodsig); ?>"/>
@@ -273,13 +261,10 @@ $editorlibs = '../../javascript/lib/';
             <td class="labelcell">Name:</td>
             <td><input type="text" name="method" value="<?php echo htmlspecialchars($method); ?>"/></td>
             <td class="labelcell">Payload:<br/>
-
                 <div id="methodpayloadbtn"></div>
             </td>
-            <td><textarea id="methodpayload" name="methodpayload" rows="1"
-                          cols="40"><?php echo htmlspecialchars($payload); ?></textarea></td>
-            <td class="labelcell" id="idcell">Msg id: <input type="text" name="id" size="3"
-                                                             value="<?php echo htmlspecialchars($id); ?>"/></td>
+            <td><textarea id="methodpayload" name="methodpayload" rows="1" cols="40"><?php echo htmlspecialchars($payload); ?></textarea></td>
+            <td class="labelcell" id="idcell">Msg id: <input type="text" name="id" size="3" value="<?php echo htmlspecialchars($id); ?>"/></td>
             <td><input type="hidden" name="wstype" value="<?php echo $wstype; ?>"/>
                 <input type="submit" value="Execute" onclick="return verifyserver();"/></td>
         </tr>
@@ -290,38 +275,18 @@ $editorlibs = '../../javascript/lib/';
             <td><h2>Client options</h2></td>
             <td class="labelcell">Show debug info:</td>
             <td><select name="debug">
-                    <option value="0"<?php if ($debug == 0) {
-                        echo ' selected="selected"';
-                    } ?>>No
-                    </option>
-                    <option value="1"<?php if ($debug == 1) {
-                        echo ' selected="selected"';
-                    } ?>>Yes
-                    </option>
-                    <option value="2"<?php if ($debug == 2) {
-                        echo ' selected="selected"';
-                    } ?>>More
-                    </option>
+                    <option value="0"<?php if ($debug == 0) { echo ' selected="selected"'; } ?>>No</option>
+                    <option value="1"<?php if ($debug == 1) { echo ' selected="selected"'; } ?>>Yes</option>
+                    <option value="2"<?php if ($debug == 2) { echo ' selected="selected"'; } ?>>More</option>
                 </select>
             </td>
             <td class="labelcell">Timeout:</td>
-            <td><input type="text" name="timeout" size="3" value="<?php if ($timeout > 0) {
-                    echo $timeout;
-                } ?>"/></td>
+            <td><input type="text" name="timeout" size="3" value="<?php if ($timeout > 0) { echo $timeout; } ?>"/></td>
             <td class="labelcell">Protocol:</td>
             <td><select name="protocol" onchange="switchssl(); switchauth(); swicthcainfo();">
-                    <option value="0"<?php if ($protocol == 0) {
-                        echo ' selected="selected"';
-                    } ?>>HTTP 1.0
-                    </option>
-                    <option value="1"<?php if ($protocol == 1) {
-                        echo ' selected="selected"';
-                    } ?>>HTTP 1.1
-                    </option>
-                    <option value="2"<?php if ($protocol == 2) {
-                        echo ' selected="selected"';
-                    } ?>>HTTPS
-                    </option>
+                    <option value="0"<?php if ($protocol == 0) { echo ' selected="selected"'; } ?>>HTTP 1.0</option>
+                    <option value="1"<?php if ($protocol == 1) { echo ' selected="selected"'; } ?>>HTTP 1.1</option>
+                    <option value="2"<?php if ($protocol == 2) { echo ' selected="selected"'; } ?>>HTTPS</option>
                 </select></td>
         </tr>
         <tr>
@@ -332,18 +297,9 @@ $editorlibs = '../../javascript/lib/';
             <td><input type="password" name="password" value="<?php echo htmlspecialchars($password); ?>"/></td>
             <td class="labelcell">Type</td>
             <td><select name="authtype">
-                    <option value="1"<?php if ($authtype == 1) {
-                        echo ' selected="selected"';
-                    } ?>>Basic
-                    </option>
-                    <option value="2"<?php if ($authtype == 2) {
-                        echo ' selected="selected"';
-                    } ?>>Digest
-                    </option>
-                    <option value="8"<?php if ($authtype == 8) {
-                        echo ' selected="selected"';
-                    } ?>>NTLM
-                    </option>
+                    <option value="1"<?php if ($authtype == 1) { echo ' selected="selected"'; } ?>>Basic</option>
+                    <option value="2"<?php if ($authtype == 2) { echo ' selected="selected"'; } ?>>Digest</option>
+                    <option value="8"<?php if ($authtype == 8) { echo ' selected="selected"'; } ?>>NTLM</option>
                 </select></td>
             <td></td>
         </tr>
@@ -351,23 +307,12 @@ $editorlibs = '../../javascript/lib/';
             <td class="labelcell">SSL:</td>
             <td class="labelcell">Verify Host's CN:</td>
             <td><select name="verifyhost">
-                    <option value="0"<?php if ($verifyhost == 0) {
-                        echo ' selected="selected"';
-                    } ?>>No
-                    </option>
-                    <option value="1"<?php if ($verifyhost == 1) {
-                        echo ' selected="selected"';
-                    } ?>>Check CN existance
-                    </option>
-                    <option value="2"<?php if ($verifyhost == 2) {
-                        echo ' selected="selected"';
-                    } ?>>Check CN match
-                    </option>
+                    <option value="0"<?php if ($verifyhost == 0) { echo ' selected="selected"'; } ?>>No</option>
+                    <option value="1"<?php if ($verifyhost == 1) { echo ' selected="selected"'; } ?>>Check CN existence</option>
+                    <option value="2"<?php if ($verifyhost == 2) { echo ' selected="selected"'; } ?>>Check CN match</option>
                 </select></td>
             <td class="labelcell">Verify Cert:</td>
-            <td><input type="checkbox" value="1" name="verifypeer" onclick="swicthcainfo();"<?php if ($verifypeer) {
-                    echo ' checked="checked"';
-                } ?> /></td>
+            <td><input type="checkbox" value="1" name="verifypeer" onclick="swicthcainfo();"<?php if ($verifypeer) { echo ' checked="checked"'; } ?> /></td>
             <td class="labelcell">CA Cert file:</td>
             <td><input type="text" name="cainfo" value="<?php echo htmlspecialchars($cainfo); ?>"/></td>
         </tr>
@@ -384,44 +329,22 @@ $editorlibs = '../../javascript/lib/';
             <td class="labelcell">COMPRESSION:</td>
             <td class="labelcell">Request:</td>
             <td><select name="requestcompression">
-                    <option value="0"<?php if ($requestcompression == 0) {
-                        echo ' selected="selected"';
-                    } ?>>None
-                    </option>
-                    <option value="1"<?php if ($requestcompression == 1) {
-                        echo ' selected="selected"';
-                    } ?>>Gzip
-                    </option>
-                    <option value="2"<?php if ($requestcompression == 2) {
-                        echo ' selected="selected"';
-                    } ?>>Deflate
-                    </option>
+                    <option value="0"<?php if ($requestcompression == 0) { echo ' selected="selected"'; } ?>>None </option>
+                    <option value="1"<?php if ($requestcompression == 1) { echo ' selected="selected"'; } ?>>Gzip</option>
+                    <option value="2"<?php if ($requestcompression == 2) { echo ' selected="selected"'; } ?>>Deflate</option>
                 </select></td>
             <td class="labelcell">Response:</td>
             <td><select name="responsecompression">
-                    <option value="0"<?php if ($responsecompression == 0) {
-                        echo ' selected="selected"';
-                    } ?>>None
-                    </option>
-                    <option value="1"<?php if ($responsecompression == 1) {
-                        echo ' selected="selected"';
-                    } ?>>Gzip
-                    </option>
-                    <option value="2"<?php if ($responsecompression == 2) {
-                        echo ' selected="selected"';
-                    } ?>>Deflate
-                    </option>
-                    <option value="3"<?php if ($responsecompression == 3) {
-                        echo ' selected="selected"';
-                    } ?>>Any
-                    </option>
+                    <option value="0"<?php if ($responsecompression == 0) { echo ' selected="selected"'; } ?>>None</option>
+                    <option value="1"<?php if ($responsecompression == 1) { echo ' selected="selected"'; } ?>>Gzip</option>
+                    <option value="2"<?php if ($responsecompression == 2) { echo ' selected="selected"'; } ?>>Deflate</option>
+                    <option value="3"<?php if ($responsecompression == 3) { echo ' selected="selected"'; } ?>>Any</option>
                 </select></td>
             <td></td>
         </tr>
         <tr>
             <td class="labelcell">COOKIES:</td>
-            <td colspan="4" class="labelcell"><input type="text" name="clientcookies" size="80"
-                                                     value="<?php echo htmlspecialchars($clientcookies); ?>"/></td>
+            <td colspan="4" class="labelcell"><input type="text" name="clientcookies" size="80" value="<?php echo htmlspecialchars($clientcookies); ?>"/></td>
             <td colspan="2">Format: 'cookie1=value1, cookie2=value2'</td>
         </tr>
     </table>
diff --git a/debugger/index.html b/debugger/index.html
deleted file mode 100644 (file)
index 87c75b9..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
-<html>
-<head>
-<title>XMLRPC Debugger</title>
-</head>
-<frameset rows="360,*">
-  <frame name="frmcontroller" src="controller.php" marginwidth="0" marginheight="0" frameborder="0" />
-  <frame name="frmaction" src="action.php" marginwidth="0" marginheight="0" frameborder="0" />
-</frameset>
-</html>
\ No newline at end of file
index fa32781..c5d6c47 100644 (file)
@@ -714,7 +714,7 @@ class Wrapper
      * valid php code is emitted.
      * Note: real spaghetti code follows...
      */
-    protected function build_remote_method_wrapper_code($client, $methodname, $xmlrpcfuncname,
+    public function build_remote_method_wrapper_code($client, $methodname, $xmlrpcfuncname,
                                                         $msig, $mdesc = '', $timeout = 0, $protocol = '', $client_copy_mode = 0, $prefix = 'xmlrpc',
                                                         $decode_php_objects = false, $encode_php_objects = false, $decode_fault = false,
                                                         $fault_response = '', $namespace = '\\PhpXmlRpc\\')
index 48b8489..8f790d3 100644 (file)
@@ -70,6 +70,9 @@ class DemoFilesTest extends PHPUnit_Framework_TestCase
         {
             curl_setopt($ch, CURLOPT_COOKIE, 'PHPUNIT_SELENIUM_TEST_ID=true');
         }
+        if ($this->args['DEBUG'] > 0) {
+            curl_setopt($ch, CURLOPT_VERBOSE, 1);
+        }
         $page = curl_exec($ch);
         curl_close($ch);
 
diff --git a/tests/6DebuggerTest.php b/tests/6DebuggerTest.php
new file mode 100644 (file)
index 0000000..6291fef
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+
+include_once __DIR__ . '/parse_args.php';
+
+class DebuggerTest extends PHPUnit_Framework_TestCase
+{
+    public $args = array();
+
+    protected $baseUrl;
+
+    protected $testId;
+    /** @var boolean $collectCodeCoverageInformation */
+    protected $collectCodeCoverageInformation;
+    protected $coverageScriptUrl;
+
+    public function run(PHPUnit_Framework_TestResult $result = NULL)
+    {
+        $this->testId = get_class($this) . '__' . $this->getName();
+
+        if ($result === NULL) {
+            $result = $this->createResult();
+        }
+
+        $this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation();
+
+        parent::run($result);
+
+        if ($this->collectCodeCoverageInformation) {
+            $coverage = new PHPUnit_Extensions_SeleniumCommon_RemoteCoverage(
+                $this->coverageScriptUrl,
+                $this->testId
+            );
+            $result->getCodeCoverage()->append(
+                $coverage->get(), $this
+            );
+        }
+
+        // do not call this before to give the time to the Listeners to run
+        //$this->getStrategy()->endOfTest($this->session);
+
+        return $result;
+    }
+
+    public function setUp()
+    {
+        $this->args = argParser::getArgs();
+
+        $this->baseUrl = $this->args['LOCALSERVER'] . str_replace( '/demo/server/server.php', '/debugger/', $this->args['URI'] );
+
+        $this->coverageScriptUrl = 'http://' . $this->args['LOCALSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['URI'] );
+    }
+
+    protected function request($file, $method = 'GET', $payload = '')
+    {
+        $url = $this->baseUrl . $file;
+
+        $ch = curl_init($url);
+        curl_setopt_array($ch, array(
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_FAILONERROR => true
+        ));
+        if ($method == 'POST')
+        {
+            curl_setopt_array($ch, array(
+                CURLOPT_POST => true,
+                CURLOPT_POSTFIELDS => $payload
+            ));
+        }
+        if ($this->collectCodeCoverageInformation)
+        {
+            curl_setopt($ch, CURLOPT_COOKIE, 'PHPUNIT_SELENIUM_TEST_ID=true');
+        }
+        if ($this->args['DEBUG'] > 0) {
+            curl_setopt($ch, CURLOPT_VERBOSE, 1);
+        }
+        $page = curl_exec($ch);
+        curl_close($ch);
+
+        $this->assertNotFalse($page);
+        $this->assertNotContains('Fatal error', $page);
+        $this->assertNotContains('Notice:', $page);
+
+        return $page;
+    }
+
+    public function testController()
+    {
+        $page = $this->request('controller.php');
+    }
+
+    /**
+     * @todo test:
+     * - list methods
+     * - describe a method
+     * - execute a method
+     * - wrap a method
+     */
+    public function testAction()
+    {
+        $page = $this->request('action.php');
+    }
+}