MMIWorkflowFunctionalTest.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. <?php
  2. /* Copyright (C) 2007-2017 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2022 Mathieu Moulin <mathieu@iprospective.fr>
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. /**
  19. * \file test/phpunit/MMIWorkflowFunctionalTest.php
  20. * \ingroup mmiworkflow
  21. * \brief Example Selenium test.
  22. *
  23. * Put detailed description here.
  24. */
  25. namespace test\functional;
  26. use PHPUnit_Extensions_Selenium2TestCase_WebDriverException;
  27. /**
  28. * Class MMIWorkflowFunctionalTest
  29. *
  30. * Requires chromedriver for Google Chrome
  31. * Requires geckodriver for Mozilla Firefox
  32. *
  33. * @fixme Firefox (Geckodriver/Marionette) support
  34. * @todo Opera linux support
  35. * @todo Windows support (IE, Google Chrome, Mozilla Firefox, Safari)
  36. * @todo OSX support (Safari, Google Chrome, Mozilla Firefox)
  37. *
  38. * @package Testmmiworkflow
  39. */
  40. class MMIWorkflowFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
  41. {
  42. // TODO: move to a global configuration file?
  43. /** @var string Base URL of the webserver under test */
  44. protected static $base_url = 'http://dev.zenfusion.fr';
  45. /**
  46. * @var string Dolibarr admin username
  47. * @see authenticate
  48. */
  49. protected static $dol_admin_user = 'admin';
  50. /**
  51. * @var string Dolibarr admin password
  52. * @see authenticate
  53. */
  54. protected static $dol_admin_pass = 'admin';
  55. /** @var int Dolibarr module ID */
  56. private static $module_id = 500000; // TODO: autodetect?
  57. /** @var array Browsers to test with */
  58. public static $browsers = array(
  59. array(
  60. 'browser' => 'Google Chrome on Linux',
  61. 'browserName' => 'chrome',
  62. 'sessionStrategy' => 'shared',
  63. 'desiredCapabilities' => array()
  64. ),
  65. // Geckodriver does not keep the session at the moment?!
  66. // XPath selectors also don't seem to work
  67. //array(
  68. // 'browser' => 'Mozilla Firefox on Linux',
  69. // 'browserName' => 'firefox',
  70. // 'sessionStrategy' => 'shared',
  71. // 'desiredCapabilities' => array(
  72. // 'marionette' => true,
  73. // ),
  74. //)
  75. );
  76. /**
  77. * Helper function to select links by href
  78. *
  79. * @param string $value Href
  80. * @return mixed Helper string
  81. */
  82. protected function byHref($value)
  83. {
  84. $anchor = null;
  85. $anchors = $this->elements($this->using('tag name')->value('a'));
  86. foreach ($anchors as $anchor) {
  87. if (strstr($anchor->attribute('href'), $value)) {
  88. break;
  89. }
  90. }
  91. return $anchor;
  92. }
  93. /**
  94. * Global test setup
  95. * @return void
  96. */
  97. public static function setUpBeforeClass()
  98. {
  99. }
  100. /**
  101. * Unit test setup
  102. * @return void
  103. */
  104. public function setUp()
  105. {
  106. $this->setSeleniumServerRequestsTimeout(3600);
  107. $this->setBrowserUrl(self::$base_url);
  108. }
  109. /**
  110. * Verify pre conditions
  111. * @return void
  112. */
  113. protected function assertPreConditions()
  114. {
  115. }
  116. /**
  117. * Handle Dolibarr authentication
  118. * @return void
  119. */
  120. private function authenticate()
  121. {
  122. try {
  123. if ($this->byId('login')) {
  124. $login = $this->byId('username');
  125. $login->clear();
  126. $login->value('admin');
  127. $password = $this->byId('password');
  128. $password->clear();
  129. $password->value('admin');
  130. $this->byId('login')->submit();
  131. }
  132. } catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
  133. // Login does not exist. Assume we are already authenticated
  134. }
  135. }
  136. /**
  137. * Test enabling developer mode
  138. * @return bool
  139. */
  140. public function testEnableDeveloperMode()
  141. {
  142. $this->url('/admin/const.php');
  143. $this->authenticate();
  144. $main_features_level_path = '//input[@value="MAIN_FEATURES_LEVEL"]/following::input[@type="text"]';
  145. $main_features_level = $this->byXPath($main_features_level_path);
  146. $main_features_level->clear();
  147. $main_features_level->value('2');
  148. $this->byName('update')->click();
  149. // Page reloaded, we need a new XPath
  150. $main_features_level = $this->byXPath($main_features_level_path);
  151. return $this->assertEquals('2', $main_features_level->value(), "MAIN_FEATURES_LEVEL value is 2");
  152. }
  153. /**
  154. * Test enabling the module
  155. *
  156. * @depends testEnableDeveloperMode
  157. * @return bool
  158. */
  159. public function testModuleEnabled()
  160. {
  161. $this->url('/admin/modules.php');
  162. $this->authenticate();
  163. $module_status_image_path = '//a[contains(@href, "'.self::$module_id.'")]/img';
  164. $module_status_image = $this->byXPath($module_status_image_path);
  165. if (strstr($module_status_image->attribute('src'), 'switch_off.png')) {
  166. // Enable the module
  167. $this->byHref('modMMIWorkflow')->click();
  168. } else {
  169. // Disable the module
  170. $this->byHref('modMMIWorkflow')->click();
  171. // Reenable the module
  172. $this->byHref('modMMIWorkflow')->click();
  173. }
  174. // Page reloaded, we need a new Xpath
  175. $module_status_image = $this->byXPath($module_status_image_path);
  176. return $this->assertContains('switch_on.png', $module_status_image->attribute('src'), "Module enabled");
  177. }
  178. /**
  179. * Test access to the configuration page
  180. *
  181. * @depends testModuleEnabled
  182. * @return bool
  183. */
  184. public function testConfigurationPage()
  185. {
  186. $this->url('/custom/mmiworkflow/admin/setup.php');
  187. $this->authenticate();
  188. return $this->assertContains('mmiworkflow/admin/setup.php', $this->url(), 'Configuration page');
  189. }
  190. /**
  191. * Test access to the about page
  192. *
  193. * @depends testConfigurationPage
  194. * @return bool
  195. */
  196. public function testAboutPage()
  197. {
  198. $this->url('/custom/mmiworkflow/admin/about.php');
  199. $this->authenticate();
  200. return $this->assertContains('mmiworkflow/admin/about.php', $this->url(), 'About page');
  201. }
  202. /**
  203. * Test about page is rendering Markdown
  204. *
  205. * @depends testAboutPage
  206. * @return bool
  207. */
  208. public function testAboutPageRendersMarkdownReadme()
  209. {
  210. $this->url('/custom/mmiworkflow/admin/about.php');
  211. $this->authenticate();
  212. return $this->assertEquals(
  213. 'Dolibarr Module Template (aka My Module)',
  214. $this->byTag('h1')->text(),
  215. "Readme title"
  216. );
  217. }
  218. /**
  219. * Test box is properly declared
  220. *
  221. * @depends testModuleEnabled
  222. * @return bool
  223. */
  224. public function testBoxDeclared()
  225. {
  226. $this->url('/admin/boxes.php');
  227. $this->authenticate();
  228. return $this->assertContains('mmiworkflowwidget1', $this->source(), "Box enabled");
  229. }
  230. /**
  231. * Test trigger is properly enabled
  232. *
  233. * @depends testModuleEnabled
  234. * @return bool
  235. */
  236. public function testTriggerDeclared()
  237. {
  238. $this->url('/admin/triggers.php');
  239. $this->authenticate();
  240. return $this->assertContains(
  241. 'interface_99_modMMIWorkflow_MMIWorkflowTriggers.class.php',
  242. $this->byTag('body')->text(),
  243. "Trigger declared"
  244. );
  245. }
  246. /**
  247. * Test trigger is properly declared
  248. *
  249. * @depends testTriggerDeclared
  250. * @return bool
  251. */
  252. public function testTriggerEnabled()
  253. {
  254. $this->url('/admin/triggers.php');
  255. $this->authenticate();
  256. return $this->assertContains(
  257. 'tick.png',
  258. $this->byXPath('//td[text()="interface_99_modMMIWorkflow_MyTrigger.class.php"]/following::img')->attribute('src'),
  259. "Trigger enabled"
  260. );
  261. }
  262. /**
  263. * Verify post conditions
  264. * @return void
  265. */
  266. protected function assertPostConditions()
  267. {
  268. }
  269. /**
  270. * Unit test teardown
  271. * @return void
  272. */
  273. public function tearDown()
  274. {
  275. }
  276. /**
  277. * Global test teardown
  278. * @return void
  279. */
  280. public static function tearDownAfterClass()
  281. {
  282. }
  283. }