Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/*** Selenium PHP driver. Saves the test command in a "out" queue (in session),* and for each selenese request, remove the first comand from the "out" queue* and push the results into the "in" queque (also in session). When "out" queque* is empty, write the results to disk.** Usage: See ../../example.php** This program is free software; you can redistribute it and/or modify* it under the terms of the BSD License.** Copyright(c) 2004 by Wei Zhuo. All rights reserved.** To contact the author write to {@link mailto:weizhuo[at]gmail[dot]com Wei Zhuo}* The latest version of PRADO can be obtained from:* {@link http://prado.sourceforge.net/}** @author Wei Zhuo <weizhuo[at]gmail[dot]com>* @version $Id: selenium.php 1771 2007-03-26 00:27:59Z xue $* @package Prado.tests*//*** Selenium automatic client runner,** @author Wei Zhuo<weizhuo[at]gmail[dot]com>* @version $Id: selenium.php 1771 2007-03-26 00:27:59Z xue $* @package Prado.tests*/require_once(dirname(__FILE__).'/results.php');class SeleniumTestRunner{protected $driver;protected $base_dir = '';public function __construct($driver=null, $base_dir='../javascript/'){if(is_null($driver) && !(php_sapi_name() == 'cli'))$driver = $_SERVER['SCRIPT_NAME'];$this->driver = $driver;$this->base_dir = $base_dir;}public function render(){if((php_sapi_name() == 'cli')) return;$file = dirname(__FILE__).'/TestRunner.php';$driver = $this->driver;//$base_dir = $this->base_dir;$base_dir = $driver.'?sr=';include($file);}public function getDriver(){return $this->driver;}}class SeleniumTestStorage{protected $outputs = array();protected $tests = array();protected $options=array();public function getTests(){return $this->tests;}public function getOptions(){return $this->options;}public function addOption($test_name, $option){$this->options[$test_name] = $option;}public function addCommand($test_case_id, $command){$data = array($test_case_id, $command);array_push($this->outputs, $data);}public function getCommand(){return array_shift($this->outputs);}public function addTestCase($command, $trace_details, $test_name, $test_suite){$data = array(0, 0, $command, "", $trace_details, $test_name, $test_suite);array_push($this->tests, $data);}}class SeleneseInterpreter{protected $storage;protected $tracer;public function __construct($storage, $tracer){$this->storage = $storage;$this->tracer = $tracer;}public function getTests(){return $this->storage->getTests();}public function getOptions(){return $this->storage->getOptions();}public function getCommand(){$command = $this->storage->getCommand();return empty($command) ? "|testComplete|||" : "{$command[1]}<{$command[0]}>";}public function __call($func, $args){if($func{0} == '_') return;$trace = debug_backtrace();if($this->isTestOptionFunction($func,$args,$trace))return;$ID = isset($args[0]) ? $args[0] : "";$value = isset($args[1]) ? $args[1] : "";if(strpos(strtolower($func),'htmlpresent') || strpos(strtolower($func),'htmlnotpresent'))$ID = htmlspecialchars($ID);$command = array($func, $ID, $value);if(is_int(strpos(strtolower($func), 'visible')))$this->addCommand(array('pause','250',''),$trace);return $this->addCommand($command, $trace);}protected function isTestOptionFunction($func,$args,$trace){if(strtolower($func)==='skipcondition'){list($trace, $test, $suite) = $this->tracer->getTrace($trace);$this->storage->addOption($test,$args[0]);return true;}return false;}protected function addCommand($command, $trace){list($trace, $test, $suite) = $this->tracer->getTrace($trace);$test_id = $this->storage->addTestCase($command, $trace, $test, $suite);$this->storage->addCommand($test_id, $command);}}class SeleniumTestTrace{protected $root;public function __construct($root){$this->root = $root;}public function getTrace($trace){$group = array_pop($trace);$info = $trace[3];$test = $group['args'][0]->getTestList();$i = count($test);$name = $test[$i-2].'::'.$test[$i-1];$suite = $test[0];unset($info['object']);/*for($i = 0; $i < count($info['args']); $i++){if($info['args'][$i] instanceof TControl)$info['args'][$i] = $info['args'][$i]->ClientID;}*/$file = str_replace($this->root, '', $info['file']);$info['file'] = substr($file, 1);return array($info, $name, $suite);}}class SimpleSeleniumProxyServer{protected $runner;protected $int;protected $result_file;public function __construct($runner, $int, $result_file){$this->int = $int;$this->runner = $runner;$this->result_file = $result_file;}public function proxy(){return $this->int;}public static function getInstance($root='/', $result_file='results.dat', $base_dir='selenium/'){static $instance;if(!isset($instance)){$storage = new SeleniumTestStorage();$tracer = new SeleniumTestTrace($root);$interpreter = new SeleneseInterpreter($storage, $tracer);$runner = new SeleniumTestRunner(null, $base_dir);$instance = new SimpleSeleniumProxyServer($runner, $interpreter, $result_file);}$instance->serveResults();return $instance;}public function handleRequest(){$client = new SeleniumTestRunnerServer($this->int, $this->runner);$client->serve();return true;}public function serveResults(){if(isset($_POST['result'])){$result = new SeleniumTestResult();$reporter = new SeleniumHtmlReporter($result);$reporter->render();exit();}}}class SeleniumTestSuiteWriter{protected $suites;protected $name;protected $runner;function __construct($suites, $name, $runner){$this->suites = $suites;$this->name = $name;$this->runner = $runner;}protected function renderHeader(){$base_dir = $this->runner->getDriver().'?sr=';include(dirname(__FILE__).'/TestSuiteHeader.php');$contents = <<<EOD<tr><td><b>{$this->name}</b></td></tr>EOD;echo $contents;}public function render(){$this->renderHeader();foreach($this->suites as $name => $suite){$file = $suite[0]['trace']['file'];$file = strtr($file,'\\','/');$option = $suite[0]['option']===null?'':' unless="'.$suite[0]['option'].'" ';$url = $this->runner->getDriver()."?case={$name}&file={$file}";echo "<tr{$option}>\n";echo "<td><a href=\"{$url}\">{$name}</a></td>\n";echo "</tr>\n";}echo $this->renderFooter();}protected function getJsTraceInfo(){$contents = "var prado_trace = {};\n";foreach($this->suites as $name => $suite){$name = $name;$contents .= "prado_trace['{$name}'] = [";$cases = array();foreach($suite as $testcase)$cases[] = "'".addslashes(htmlspecialchars(serialize($testcase['trace'])))."'";$contents .= implode(",\n", $cases)."];\n\n";}return $contents;}protected function renderFooter(){$trace = '';//$this->getJsTraceInfo();$contents = <<<EOD</tbody></table><br /><em>Not supported in this browser</em><table id="skippedTests" cellpadding="1"cellspacing="1"border="1"class="selenium"><tbody><tr><td><b>Skipped Tests</b></td></tr></tbody></table><script type="text/javascript">/*<![CDATA[*/$trace/*]]>*/</script></body></html>EOD;return $contents;}}class SeleniumTestCaseWriter{protected $case;protected $tests;function __construct($case, $tests){$this->case = $case;$this->tests = $tests;}protected function renderHeader(){$contents = <<<EOD<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>{$this->case}</title><meta content="text/html; charset=UTF-8" http-equiv="content-type"></head><body><table cellpadding="1" cellspacing="1" border="1" id=TABLE1><tbody><tr><td rowspan="1" colspan="3"><strong>{$this->case}</strong></td></tr>EOD;return $contents;}public function render(){echo $this->renderHeader();foreach($this->tests as $test){$t = $test['test'];if($t[0] == "open")$t[1] = "<a href=\"{$t[1]}\" target=\"_blank\">{$t[1]}</a>";echo "<tr>\n";echo "<td>{$t[0]}</td>\n";echo "<td>{$t[1]}</td>\n";echo "<td>{$t[2]}</td>\n";echo "</tr>\n";}echo $this->renderFooter();}protected function renderFooter(){$contents = <<<EOD</tbody></table></body></html>EOD;return $contents;}}class SeleniumTestRunnerServer{protected $cases = array();protected $trace = array();protected $name;protected $runner;public function __construct($int, $runner){$this->runner = $runner;$this->initialize($int);}protected function initialize($int){$options = $int->getOptions();foreach($int->getTests() as $command){$case = $command[5];$option=isset($options[$case])?$options[$case]:null;$this->cases[$case][] =array('test' => $command[2],'trace' => $command[4], 'option'=>$option);if(is_null($this->name))$this->name = $command[6];}}function serve(){if($this->isTestSuiteRequest()){$testSuite = new SeleniumTestSuiteWriter($this->cases,$this->name, $this->runner);$testSuite->render();}else if($this->isTestCaseRequest()){if(($case = $this->getTestCaseRequest()) !== false){$testCase = new SeleniumTestCaseWriter($case, $this->getTestCase());$testCase->render();}}else{$this->runner->render();}}protected function isTestSuiteRequest(){return isset($_GET['testSuites']);}protected function isTestCaseRequest(){return isset($_GET['case']);}public function isClientRequest(){return !$this->isTestSuiteRequest() && !$this->isTestCaseRequest();}protected function getTestCaseRequest(){$case = $_GET['case'];if(isset($this->cases[$case]))return $case;else return false;}protected function getTestCase(){$case = $_GET['case'];if(isset($this->cases[$case]))return $this->cases[$case];elsereturn array();}}class SeleniumTestCase extends UnitTestCase{protected $selenium;protected $Page;const KONQUEROR='browserVersion.isKonqueror';const OPERA='browserVersion.isOpera';const CHROME='browserVersion.isChrome';const INTERNET_EXPLORER='browserVersion.isIE';const SAFARI='browserVersion.isSafari';const KHTML='browserVersion.khtml';const FIREFOX='browserVersion.isFirefox';const MOZILLA='browserVersion.isMozilla';const GECKO='browserVersion.isGecko';protected $options=array();function __construct(){$server = SimpleSeleniumProxyServer::getInstance();if(!is_null($server))$this->selenium = $server->proxy();parent::__construct();}function getPage($class){$info = new ReflectionClass($class);return Prado::getApplication()->getTestPage($info->getFileName());}function __call($func, $args){if(count($args) == 0)return $this->selenium->{$func}();else if (count($args) == 1)return $this->selenium->{$func}($args[0]);else if (count($args) == 2)return $this->selenium->{$func}($args[0], $args[1]);}function disabled(){$this->selenium->skipCondition('DISABLED');}function skipBrowsers(){$conditions = $this->getBrowserOptions(func_get_args());$this->selenium->skipCondition($conditions);}protected function getBrowserOptions($arg_list){$browsers=array();foreach($arg_list as $arg){if(is_array($arg))$browsers[] = '('.implode(' && ', $arg).')';else$browsers[] = $arg;}return implode(' || ', $browsers);}function targetBrowsers(){$conditions = $this->getBrowserOptions(func_get_args());$this->selenium->skipCondition("!(".$conditions.")");}}?>