PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/app/protected/tests/functional/TestSuite.php

https://bitbucket.org/markwu/zurmo
PHP | 760 lines | 713 code | 11 blank | 36 comment | 36 complexity | 1bbb56e11f39000925e43fe5b9629069 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-3.0, LGPL-2.1, BSD-2-Clause, AGPL-3.0
  1. <?php
  2. /*********************************************************************************
  3. * Zurmo is a customer relationship management program developed by
  4. * Zurmo, Inc. Copyright (C) 2013 Zurmo Inc.
  5. *
  6. * Zurmo is free software; you can redistribute it and/or modify it under
  7. * the terms of the GNU Affero General Public License version 3 as published by the
  8. * Free Software Foundation with the addition of the following permission added
  9. * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
  10. * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
  11. * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
  12. *
  13. * Zurmo is distributed in the hope that it will be useful, but WITHOUT
  14. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  15. * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License along with
  19. * this program; if not, see http://www.gnu.org/licenses or write to the Free
  20. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  21. * 02110-1301 USA.
  22. *
  23. * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
  24. * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
  25. *
  26. * The interactive user interfaces in original and modified versions
  27. * of this program must display Appropriate Legal Notices, as required under
  28. * Section 5 of the GNU Affero General Public License version 3.
  29. *
  30. * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
  31. * these Appropriate Legal Notices must retain the display of the Zurmo
  32. * logo and Zurmo copyright notice. If the display of the logo is not reasonably
  33. * feasible for technical reasons, the Appropriate Legal Notices must display the words
  34. * "Copyright Zurmo Inc. 2013. All rights reserved".
  35. ********************************************************************************/
  36. $basePath = realpath(dirname(__FILE__) . '/../../../');
  37. require_once('../PhpUnitServiceUtil.php');
  38. require_once 'File/Iterator.php';
  39. require_once('File/Iterator/Factory.php');
  40. if (is_file($basePath . '/protected/config/debugTest.php'))
  41. {
  42. require_once($basePath . '/protected/config/debugTest.php');
  43. }
  44. else
  45. {
  46. copy($basePath . '/protected/config/debugDIST.php', $basePath . '/protected/config/debugTest.php');
  47. die('Please configure functional tests in config file ' . $basePath . '/protected/config/debugTest.php');
  48. }
  49. define('SELENIUM_SERVER_PATH', $seleniumServerPath);
  50. define('TEST_BASE_URL', $seleniumTestBaseUrl);
  51. define('TEST_RESULTS_URL', $seleniumTestResultUrl);
  52. define('TEST_RESULTS_PATH', $seleniumTestResultsPath);
  53. //following is path to the user-extension.js, so as to enable the use of global variables
  54. define('USER_EXTENSIONS_JS_PATH', './assets/extensions/user-extensions.js');
  55. define('SELENIUM_SERVER_PORT', $seleniumServerPort);
  56. define('BROWSERS_TO_RUN', $seleniumBrowsersToRun);
  57. define('TEST_BASE_CONTROL_URL', $seleniumControlUrl);
  58. class TestSuite
  59. {
  60. public static function run()
  61. {
  62. global $argv, $argc;
  63. $usage = "\n" .
  64. " Usage: php [options] TestSuite.php <All|Misc|moduleName|TestClassName> [options]\n" .
  65. "\n" .
  66. " All Run all tests.\n" .
  67. " Framework Run all tests in framework/tests/functional.\n" .
  68. " Misc Run the test suites in app/protected/tests/functional.\n" .
  69. " moduleName Run the test suites in app/protected/modules/moduleName/tests/functional.\n" .
  70. " TestClassName Run the tests in TestClassName.html, wherever that happens to be.\n" .
  71. " options\n" .
  72. " -p port Example: -p4044\n" .
  73. " -h host Example: -hhttp://www.sitetotest/app/\n" .
  74. " -b browser <*firefox|*iexplore> if not specified, will run all in browsers \n" .
  75. " -c test server control url Example: -chttp://www.sitetotest/controlUrl.php\n" .
  76. " Example: -b*firefox \n" .
  77. " -userExtensions Example: -userExtensions pathToTheUserExtensionJS \n" .
  78. "\n" .
  79. " Examples:\n" .
  80. "\n" .
  81. " php TestSuiteSelenium.php accounts (Run the tests in the Accounts module.)\n" .
  82. " php TestSuiteSelenium.php RedBeanModelTest (Run the test suite RedBeanModelTest.html.)\n" .
  83. "\n" .
  84. " Note:\n" .
  85. "\n" ;
  86. PhpUnitServiceUtil::checkVersion();
  87. if ($argv[0] != 'TestSuite.php')
  88. {
  89. echo $usage;
  90. exit;
  91. }
  92. else
  93. {
  94. $whatToTest = $argv[1];
  95. }
  96. $whatToTestIsModuleDir = self::isWhatToTestAModule($whatToTest);
  97. $suiteNames = array();
  98. $htmlTestSuiteFiles = array();
  99. if ($whatToTest == 'All' || $whatToTest == 'Misc' || !$whatToTestIsModuleDir)
  100. {
  101. $compareToTest = $whatToTest;
  102. if ($whatToTest == 'Misc')
  103. {
  104. $compareToTest = null;
  105. }
  106. $htmlTestSuiteFiles = self::buildSuiteFromSeleneseDirectory($htmlTestSuiteFiles, '.', $compareToTest);
  107. }
  108. if ($whatToTest != 'Misc' && !$whatToTestIsModuleDir)
  109. {
  110. $compareToTest = $whatToTest;
  111. if ($whatToTest == 'Framework')
  112. {
  113. $compareToTest = null;
  114. }
  115. $frameworkTestSuiteDirectory = '../../core/tests/functional';
  116. $htmlTestSuiteFiles = self::buildSuiteFromSeleneseDirectory(
  117. $htmlTestSuiteFiles, $frameworkTestSuiteDirectory, $compareToTest);
  118. }
  119. $moduleDirectoryName = '../../modules';
  120. if (is_dir($moduleDirectoryName))
  121. {
  122. $moduleNames = scandir($moduleDirectoryName);
  123. foreach ($moduleNames as $moduleName)
  124. {
  125. if ($moduleName != '.' &&
  126. $moduleName != '..')
  127. {
  128. $moduleFunctionalTestDirectoryName = "$moduleDirectoryName/$moduleName/tests/functional";
  129. if (is_dir($moduleFunctionalTestDirectoryName))
  130. {
  131. if ($whatToTest == 'All' ||
  132. // Allow specifying 'Users' for the module name 'users'.
  133. $whatToTest == $moduleName ||
  134. strtolower($whatToTest) == $moduleName || !$whatToTestIsModuleDir)
  135. {
  136. if ($whatToTest == $moduleName || strtolower($whatToTest) == $moduleName)
  137. {
  138. $compareToTest = null;
  139. }
  140. else
  141. {
  142. $compareToTest = $whatToTest;
  143. }
  144. $htmlTestSuiteFiles = self::buildSuiteFromSeleneseDirectory(
  145. $htmlTestSuiteFiles, $moduleFunctionalTestDirectoryName, $compareToTest);
  146. }
  147. }
  148. }
  149. }
  150. }
  151. if (count($htmlTestSuiteFiles) == 0)
  152. {
  153. echo $usage;
  154. echo " No tests found for '$whatToTest'.\n\n";
  155. exit;
  156. }
  157. echo 'Suites to run:' . "\n";
  158. foreach ($htmlTestSuiteFiles as $pathToSuite)
  159. {
  160. if (in_array(basename($pathToSuite), $suiteNames))
  161. {
  162. echo 'Cannot run tests because there are 2 test suites with the same name.' . "\n";
  163. echo 'The duplicate found is here: ' . $pathToSuite . "\n";
  164. exit;
  165. }
  166. $suiteNames[] = basename($pathToSuite);
  167. echo $pathToSuite . "\n";
  168. }
  169. echo 'Running Test Suites using Selenium RC v2:' . "\n";
  170. $browsersToRun = self::resolveBrowserFromParameter();
  171. foreach ($browsersToRun as $browserId => $browserDisplayName)
  172. {
  173. self::clearPreviousTestResultsByServerAndBrowser(self::getServerByServerControlUrl(self::resolveHostFromParameterAndConstant()),
  174. $browserDisplayName);
  175. foreach ($htmlTestSuiteFiles as $pathToSuite)
  176. {
  177. if (!self::isInstallationTest($pathToSuite))
  178. {
  179. echo "Restoring test db\n";
  180. self::remoteAction(self::resolveServerControlUrlFromParameterAndConstant(), array('action' => 'restore'));
  181. echo "Restored test db\n";
  182. if (!self::isInstallationTest($pathToSuite))
  183. {
  184. echo "Set user default time zone.\n";
  185. self::remoteAction(self::resolveServerControlUrlFromParameterAndConstant(), array('action' => 'setUserDefaultTimezone'));
  186. echo "User default time zone set.\n";
  187. }
  188. echo "Clear cache on remote server\n";
  189. self::remoteAction(self::resolveHostFromParameterAndConstant(), array('clearCache' => '1',
  190. 'ignoreBrowserCheck' => '1'));
  191. }
  192. else
  193. {
  194. echo "Uninstall zurmo\n";
  195. self::remoteAction(self::resolveServerControlUrlFromParameterAndConstant(), array('action' => 'backupRemovePerInstance'));
  196. }
  197. echo "Cache cleared\n";
  198. echo 'Running test suite: ';
  199. echo $pathToSuite . "\n";
  200. $host = self::resolveHostFromParameterAndConstant();
  201. $hostFilePart = str_replace('http://', '', $host);
  202. $hostFilePart = str_replace('https://', '', $hostFilePart);
  203. $hostFilePart = str_replace('/', '', $hostFilePart);
  204. $hostFilePart = $hostFilePart . '.';
  205. $testResultFileNamePrefix = str_replace('../', '', $pathToSuite);
  206. $testResultFileNamePrefix = str_replace('/', '.', $testResultFileNamePrefix);
  207. $testResultFileNamePrefix = str_replace('\\', '.', $testResultFileNamePrefix);
  208. $testResultFileNamePrefix = str_replace('..', '', $testResultFileNamePrefix);
  209. $testResultFileNamePrefix = str_replace('.html', '', $testResultFileNamePrefix);
  210. $testResultsFileName = $testResultFileNamePrefix . '.' . str_replace(' ', '', $browserDisplayName) . '.TestResults.html';
  211. $finalTestResultsPath = TEST_RESULTS_PATH . $hostFilePart . $testResultsFileName;
  212. $finalCommand = 'java -jar "' . SELENIUM_SERVER_PATH .'" ';
  213. $finalCommand .= '-port ' . self::resolvePortFromParameterAndConstant();
  214. $finalCommand .= ' -htmlSuite ' . $browserId . ' ';
  215. $finalCommand .= $host . ' ' . realPath($pathToSuite) . ' ' . $finalTestResultsPath;
  216. $finalCommand .= ' -userExtensions ' . self::resolveUserExtensionsJsFromParameterAndConstant();
  217. echo $finalCommand . "\n";
  218. exec($finalCommand);
  219. echo 'Restoring test db';
  220. self::remoteAction(self::resolveServerControlUrlFromParameterAndConstant(), array('action' => 'restore'));
  221. if (self::isInstallationTest($pathToSuite))
  222. {
  223. self::remoteAction(self::resolveServerControlUrlFromParameterAndConstant(), array('action' => 'restorePerInstance'));
  224. }
  225. }
  226. }
  227. echo 'Functional Run Complete.' . "\n";
  228. self::updateTestResultsSummaryAndDetailsFiles();
  229. }
  230. public static function buildSuiteFromSeleneseDirectory($htmlTestSuiteFiles, $directoryName, $whatToTest = null)
  231. {
  232. $files = array_merge(
  233. self::getSeleneseFiles($directoryName, '.html')
  234. );
  235. foreach ($files as $file)
  236. {
  237. if (!strpos($file, 'TestSuite') === false)
  238. {
  239. if ( $whatToTest == null || $whatToTest == 'All' ||
  240. ($whatToTest . '.html' == basename($file) && $whatToTest != null))
  241. {
  242. $htmlTestSuiteFiles[] = $file;
  243. }
  244. }
  245. }
  246. return $htmlTestSuiteFiles;
  247. }
  248. /**
  249. * @param string $directory
  250. * @param string $suffix
  251. * @return array
  252. * @since Method available since Release 3.3.0
  253. */
  254. protected static function getSeleneseFiles($directory, $suffix)
  255. {
  256. $files = array();
  257. $iterator = File_Iterator_Factory::getFileIterator($directory, $suffix);
  258. foreach ($iterator as $file)
  259. {
  260. if (!in_array($file, $files))
  261. {
  262. $files[] = (string)$file;
  263. }
  264. }
  265. return $files;
  266. }
  267. /**
  268. * @return true if what to test is a module directory
  269. */
  270. protected static function isWhatToTestAModule($whatToTest)
  271. {
  272. $moduleDirectoryName = '../../modules';
  273. if (is_dir($moduleDirectoryName))
  274. {
  275. $moduleNames = scandir($moduleDirectoryName);
  276. foreach ($moduleNames as $moduleName)
  277. {
  278. if ($moduleName != '.' &&
  279. $moduleName != '..')
  280. {
  281. $moduleFunctionalTestDirectoryName = "$moduleDirectoryName/$moduleName/tests/functional";
  282. if (is_dir($moduleFunctionalTestDirectoryName))
  283. {
  284. if (// Allow specifying 'Users' for the module name 'users'.
  285. $whatToTest == $moduleName ||
  286. ucfirst($whatToTest) == $moduleName)
  287. {
  288. return true;
  289. }
  290. }
  291. }
  292. }
  293. }
  294. return false;
  295. }
  296. protected static function resolvePortFromParameterAndConstant()
  297. {
  298. global $argv, $argc;
  299. for ($i = 0; $i < ($argc); $i++)
  300. {
  301. if (substr($argv[$i], 0, 2) == '-p')
  302. {
  303. return substr($argv[$i], 2);
  304. }
  305. }
  306. return SELENIUM_SERVER_PORT;
  307. }
  308. protected static function resolveHostFromParameterAndConstant()
  309. {
  310. global $argv, $argc;
  311. for ($i = 0; $i < ($argc); $i++)
  312. {
  313. if (substr($argv[$i], 0, 2) == '-h')
  314. {
  315. return substr($argv[$i], 2);
  316. }
  317. }
  318. return TEST_BASE_URL;
  319. }
  320. protected static function resolveServerControlUrlFromParameterAndConstant()
  321. {
  322. global $argv, $argc;
  323. for ($i = 0; $i < ($argc); $i++)
  324. {
  325. if (substr($argv[$i], 0, 2) == '-c')
  326. {
  327. return substr($argv[$i], 2);
  328. }
  329. }
  330. return TEST_BASE_CONTROL_URL;
  331. }
  332. protected static function resolveUserExtensionsJsFromParameterAndConstant()
  333. {
  334. global $argv, $argc;
  335. for ($i = 0; $i < ($argc); $i++)
  336. {
  337. if (substr($argv[$i], 0, 16) == '-userExtensions ')
  338. {
  339. return substr($argv[$i], 16);
  340. }
  341. }
  342. return USER_EXTENSIONS_JS_PATH;
  343. }
  344. protected static function resolveBrowserFromParameter()
  345. {
  346. global $argv, $argc;
  347. $browserData = self::getBrowsersData();
  348. for ($i = 0; $i < ($argc); $i++)
  349. {
  350. if (substr($argv[$i], 0, 2) == '-b')
  351. {
  352. $browsersToRun = substr($argv[$i], 2);
  353. if ($browsersToRun == BROWSERS_TO_RUN)
  354. {
  355. return self::getBrowsersData();
  356. }
  357. if (!in_array($browsersToRun,
  358. array('*iexplore', '*firefox', '*googlechrome')))
  359. {
  360. echo 'Invalid Browser specified.' . "\n";
  361. echo 'Specified Browser: ' . $browsersToRun . "\n";
  362. exit;
  363. }
  364. foreach ($browserData as $id => $name)
  365. {
  366. if ($id == $browsersToRun)
  367. {
  368. return array($id => $name);
  369. }
  370. }
  371. }
  372. }
  373. return self::getBrowsersData();
  374. }
  375. protected static function getServerByServerControlUrl($url)
  376. {
  377. if (stristr($url, 'dev9.zurmo.com'))
  378. {
  379. return 'dev9.zurmo.com';
  380. }
  381. elseif (stristr($url, 'dev8.zurmo.com'))
  382. {
  383. return 'dev8.zurmo.com';
  384. }
  385. return 'Unknown';
  386. }
  387. protected static function getBrowsersData()
  388. {
  389. return array(
  390. '*firefox' => 'FireFox',
  391. '*iexplore' => 'Internet Explorer',
  392. '*googlechrome' => 'Chrome',
  393. );
  394. }
  395. protected static function updateTestResultsSummaryAndDetailsFiles()
  396. {
  397. $data = array();
  398. if (is_dir(TEST_RESULTS_PATH))
  399. {
  400. $resultsNames = scandir(TEST_RESULTS_PATH);
  401. foreach ($resultsNames as $resultFile)
  402. {
  403. if ($resultFile != '.' &&
  404. $resultFile != '..' &&
  405. $resultFile != 'Summary.html' &&
  406. $resultFile != 'Details.html')
  407. {
  408. $data[] = array(
  409. 'fileName' => $resultFile,
  410. 'modifiedDate' => date ("F d Y H:i:s.", filemtime(TEST_RESULTS_PATH . $resultFile)),
  411. 'status' => self::getResultFileStatusByFileName($resultFile),
  412. 'browser' => self::getResultFileBrowserByFileName($resultFile),
  413. 'server' => self::getResultServerByFileName($resultFile),
  414. );
  415. }
  416. }
  417. }
  418. self::makeResultsDetailsFile($data);
  419. self::makeResultsSummaryFile($data);
  420. }
  421. protected static function clearPreviousTestResultsByServerAndBrowser($server, $browserDisplayName)
  422. {
  423. if (is_dir(TEST_RESULTS_PATH))
  424. {
  425. $resultsNames = scandir(TEST_RESULTS_PATH);
  426. foreach ($resultsNames as $resultFile)
  427. {
  428. if ($resultFile != '.' &&
  429. $resultFile != '..' &&
  430. stristr($resultFile, strtolower($browserDisplayName)) &&
  431. stristr($resultFile, strtolower($server)))
  432. {
  433. unlink(TEST_RESULTS_PATH . $resultFile);
  434. }
  435. }
  436. }
  437. }
  438. protected static function getResultFileStatusByFileName($resultFile)
  439. {
  440. $contents = file_get_contents(TEST_RESULTS_PATH . $resultFile);
  441. $contents = str_replace('"', '', $contents);
  442. $contents = strtolower($contents);
  443. $pieces = explode('id=suitetable', $contents); // Not Coding Standard
  444. if (!empty($pieces[1]))
  445. {
  446. $pieces = explode('</table>', $pieces[1]);
  447. $pieces = explode('<tr class=title', $pieces[0]); // Not Coding Standard
  448. $pieces = explode('>', $pieces[1]);
  449. return trim($pieces[0]);
  450. }
  451. return 'Unknown';
  452. }
  453. protected static function getResultFileBrowserByFileName($resultFile)
  454. {
  455. if (stristr($resultFile, 'firefox'))
  456. {
  457. return 'Firefox';
  458. }
  459. elseif (stristr($resultFile, 'internetexplorer'))
  460. {
  461. return 'IE';
  462. }
  463. elseif (stristr($resultFile, 'chrome'))
  464. {
  465. return 'Chrome';
  466. }
  467. return 'Unknown';
  468. }
  469. protected static function getResultServerByFileName($resultFile)
  470. {
  471. if (stristr($resultFile, 'dev9.zurmo.com'))
  472. {
  473. return 'dev9.zurmo.com';
  474. }
  475. elseif (stristr($resultFile, 'dev8.zurmo.com'))
  476. {
  477. return 'dev8.zurmo.com';
  478. }
  479. return 'Unknown';
  480. }
  481. protected static function makeResultsDetailsFile($data)
  482. {
  483. $fileName = TEST_RESULTS_PATH . 'Details.html';
  484. $content = '<html>';
  485. $content .= '<table border="1" width="100%">' . "\n";
  486. $content .= '<tr>' . "\n";
  487. $content .= '<td>Status</td>' . "\n";
  488. $content .= '<td>Server</td>' . "\n";
  489. $content .= '<td>Browser</td>' . "\n";
  490. $content .= '<td>Date</td>' . "\n";
  491. $content .= '<td>File</td>' . "\n";
  492. $content .= '</tr>' . "\n";
  493. foreach ($data as $info)
  494. {
  495. $link = '<a href="' . TEST_RESULTS_URL . $info['fileName'] . '">' . $info['fileName'] . '</a>';
  496. $statusColor = 'bgcolor="red"';
  497. if ($info['status']=='status_passed')
  498. {
  499. $statusColor = 'bgcolor="green"';
  500. }
  501. $content .= '<tr>' . "\n";
  502. $content .= '<td ' . $statusColor . '>' . $info['status'] . '</td>' . "\n";
  503. $content .= '<td>' . $info['server'] . '</td>' . "\n";
  504. $content .= '<td>' . $info['browser'] . '</td>' . "\n";
  505. $content .= '<td>' . $info['modifiedDate'] . '</td>' . "\n";
  506. $content .= '<td>' . $link . '</td>' . "\n";
  507. $content .= '</tr>' . "\n";
  508. }
  509. $content .= '</table>' . "\n";
  510. $content .= '</html>' . "\n";
  511. if (is_writable(TEST_RESULTS_PATH))
  512. {
  513. if (!$handle = fopen($fileName, 'w'))
  514. {
  515. echo "Cannot open file ($fileName)";
  516. exit;
  517. }
  518. // Write $somecontent to our opened file.
  519. if (fwrite($handle, $content) === false)
  520. {
  521. echo "Cannot write to file ($fileName)";
  522. exit;
  523. }
  524. fclose($handle);
  525. }
  526. else
  527. {
  528. echo "The file $fileName is not writable";
  529. }
  530. }
  531. protected static function makeResultsSummaryFile($data)
  532. {
  533. $content = '<html>';
  534. $content .= '<table border="1" width="100%">' . "\n";
  535. $content .= '<tr>' . "\n";
  536. $content .= '<td>Status</td>' . "\n";
  537. $content .= '<td>Server</td>' . "\n";
  538. $content .= '<td>Browser</td>' . "\n";
  539. $content .= '<td>Date</td>' . "\n";
  540. $content .= '<td>Test Passed</td>' . "\n";
  541. $content .= '<td>Tests Failed</td>' . "\n";
  542. $content .= '<td>Details</td>' . "\n";
  543. $content .= '</tr>' . "\n";
  544. $link = '<a href="' . TEST_RESULTS_URL . 'Details.html">Details</a>';
  545. $allBrowsersStats = array();
  546. foreach ($data as $info)
  547. {
  548. if (count($allBrowsersStats) == 0 || !in_array($info['browser'], $allBrowsersStats))
  549. {
  550. $allBrowsersStats[$info['server']][$info['browser']] = array();
  551. $allBrowsersStats[$info['server']][$info['browser']]['testsPassed'] = 0;
  552. $allBrowsersStats[$info['server']][$info['browser']]['testsFailed'] = 0;
  553. $allBrowsersStats[$info['server']][$info['browser']]['modifiedDate'] = 0;
  554. }
  555. }
  556. foreach ($data as $info)
  557. {
  558. if ($info['status']=='status_passed')
  559. {
  560. $allBrowsersStats[$info['server']][$info['browser']]['testsPassed']++;
  561. }
  562. else
  563. {
  564. $allBrowsersStats[$info['server']][$info['browser']]['testsFailed']++;
  565. }
  566. if (strtotime($allBrowsersStats[$info['server']][$info['browser']]['modifiedDate']) < strtotime($info['modifiedDate']))
  567. {
  568. $allBrowsersStats[$info['server']][$info['browser']]['modifiedDate'] = $info['modifiedDate'];
  569. }
  570. }
  571. foreach ($allBrowsersStats as $server => $serverStats)
  572. {
  573. foreach ($serverStats as $browser => $browserStats)
  574. {
  575. if ($browserStats['testsFailed'] > 0 || $browserStats['testsPassed'] <= 0)
  576. {
  577. $status = 'status_failed';
  578. }
  579. else
  580. {
  581. $status = 'status_passed';
  582. }
  583. $statusColor = 'bgcolor="red"';
  584. if ($status == 'status_passed')
  585. {
  586. $statusColor = 'bgcolor="green"';
  587. }
  588. $content .= '<tr>' . "\n";
  589. $content .= '<td ' . $statusColor . '>' . $status . '</td>' . "\n";
  590. $content .= '<td>' . $server . '</td>' . "\n";
  591. $content .= '<td>' . $browser . '</td>' . "\n";
  592. $content .= '<td>' . $browserStats['modifiedDate'] . '</td>' . "\n";
  593. $content .= '<td>' . $browserStats['testsPassed'] . '</td>' . "\n";
  594. $content .= '<td>' . $browserStats['testsFailed'] . '</td>' . "\n";
  595. $content .= '<td>' . $link . '</td>' . "\n";
  596. $content .= '</tr>' . "\n";
  597. }
  598. }
  599. $content .= '</table>' . "\n";
  600. $content .= '</html>' . "\n";
  601. $fileName = TEST_RESULTS_PATH . 'Summary.html';
  602. if (is_writable(TEST_RESULTS_PATH))
  603. {
  604. if (!$handle = fopen($fileName, 'w'))
  605. {
  606. echo "Cannot open file ($fileName)";
  607. exit;
  608. }
  609. // Write $somecontent to our opened file.
  610. if (fwrite($handle, $content) === false)
  611. {
  612. echo "Cannot write to file ($fileName)";
  613. exit;
  614. }
  615. fclose($handle);
  616. }
  617. else
  618. {
  619. echo "The file $fileName is not writable";
  620. }
  621. }
  622. /**
  623. * Restore database
  624. * @param string url
  625. * @param string $action
  626. */
  627. protected static function remoteAction($url, $params)
  628. {
  629. if (!$url)
  630. {
  631. echo "Invalid db control url";
  632. exit;
  633. }
  634. if (isset($params['action']) && in_array($params['action'], array('restore', 'backupRemovePerInstance', 'restorePerInstance', 'setUserDefaultTimezone')))
  635. {
  636. $url = $url . "?action=" . urlencode($params['action']);
  637. }
  638. elseif (isset($params['clearCache']) && $params['clearCache'] == '1' &&
  639. isset($params['ignoreBrowserCheck']) && $params['ignoreBrowserCheck'] == '1')
  640. {
  641. $url = $url . "index.php/zurmo/default/login?clearCache=1&ignoreBrowserCheck=1"; // Not Coding Standard
  642. }
  643. else
  644. {
  645. echo "Invalid params";
  646. exit;
  647. }
  648. $ch = curl_init();
  649. curl_setopt($ch, CURLOPT_URL, $url);
  650. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  651. curl_setopt($ch, CURLOPT_TIMEOUT, 120);
  652. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
  653. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true );
  654. curl_setopt($ch, CURLOPT_MAXREDIRS, 10 );
  655. curl_exec($ch);
  656. $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  657. $error_info = curl_error($ch);
  658. curl_close($ch);
  659. if ($httpcode == 200)
  660. {
  661. return true;
  662. }
  663. else
  664. {
  665. echo $error_info;
  666. exit;
  667. }
  668. }
  669. /**
  670. * Determine is suite is installation test suite.
  671. * @param string $path
  672. * @return boolen
  673. */
  674. protected static function isInstallationTest($path)
  675. {
  676. $position = strpos($path, 'InstallationTestSuite.html');
  677. if ($position !== false)
  678. {
  679. return true;
  680. }
  681. else
  682. {
  683. return false;
  684. }
  685. }
  686. /**
  687. * Determine is suite is actually default timezone test.
  688. * @param string $path
  689. * @return boolen
  690. */
  691. protected static function isDefaultTimeZoneTest($path)
  692. {
  693. $position = strpos($path, DIRECTORY_SEPARATOR . 'TestSuite.html');
  694. if ($position !== false)
  695. {
  696. return true;
  697. }
  698. else
  699. {
  700. return false;
  701. }
  702. }
  703. }
  704. $testRunner = new TestSuite();
  705. $testRunner->run();
  706. ?>