FeatureContext.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. <?php
  2. use Behat\Gherkin\Node\TableNode;
  3. use Behat\MinkExtension\Context\MinkContext;
  4. /**
  5. * Features context. (MinkContext extends BehatContext)
  6. */
  7. class FeatureContext extends MinkContext
  8. {
  9. /**
  10. * Initializes context.
  11. * Every scenario gets its own context object.
  12. */
  13. public function __construct()
  14. {
  15. }
  16. /**
  17. * @Given /^I am a platform administrator$/
  18. */
  19. public function iAmAPlatformAdministrator()
  20. {
  21. $this->iAmLoggedAs('admin');
  22. $this->getSession()->back();
  23. }
  24. /**
  25. * @Given /^I am a teacher$/
  26. */
  27. public function iAmATeacher()
  28. {
  29. $this->iAmLoggedAs('mmosquera');
  30. }
  31. /**
  32. * @Given /^I am a student$/
  33. */
  34. public function iAmAStudent()
  35. {
  36. $this->iAmLoggedAs('acostea');
  37. }
  38. /**
  39. * @Given /^I am an HR manager$/
  40. */
  41. public function iAmAnHR()
  42. {
  43. $this->iAmLoggedAs('ptook');
  44. }
  45. /**
  46. * @Given /^I am a student boss$/
  47. */
  48. public function iAmAStudentBoss()
  49. {
  50. $this->iAmLoggedAs('abaggins');
  51. }
  52. /**
  53. * @Given /^I am an invitee$/
  54. */
  55. public function iAmAnInvitee()
  56. {
  57. $this->iAmLoggedAs('bproudfoot');
  58. }
  59. /**
  60. * @Given /^course "([^"]*)" exists$/
  61. */
  62. public function courseExists($argument)
  63. {
  64. $this->iAmAPlatformAdministrator();
  65. $this->visit('/main/admin/course_list.php?keyword='.$argument);
  66. $this->assertPageContainsText($argument);
  67. }
  68. /**
  69. * @Given /^course "([^"]*)" is deleted$/
  70. */
  71. public function courseIsDeleted($argument)
  72. {
  73. $this->iAmAPlatformAdministrator();
  74. $this->visit('/main/admin/course_list.php?keyword='.$argument);
  75. $this->clickLink('Delete');
  76. }
  77. /**
  78. * @Given /^I am on course "([^"]*)" homepage$/
  79. */
  80. public function iAmOnCourseXHomepage($courseCode)
  81. {
  82. $this->visit('/courses/'.$courseCode.'/index.php');
  83. $this->assertElementNotOnPage('.alert-danger');
  84. }
  85. /**
  86. * @Given /^I am on course "([^"]*)" homepage in session "([^"]*)"$/
  87. */
  88. public function iAmOnCourseXHomepageInSessionY($courseCode, $sessionName)
  89. {
  90. $this->visit('/main/course_home/redirect.php?cidReq='.$courseCode.'&session_name='.$sessionName);
  91. }
  92. /**
  93. * @Given /^I am a "([^"]*)" user$/
  94. */
  95. public function iAmAXUser($argument)
  96. {
  97. $this->visit('/main/auth/profile.php');
  98. $this->assertFieldContains('language', $argument);
  99. }
  100. /**
  101. * @Given /^I am logged as "([^"]*)"$/
  102. */
  103. public function iAmLoggedAs($username)
  104. {
  105. $this->visit('/public/logout');
  106. $this->visit('/public/login');
  107. $this->fillField('login__username', $username);
  108. $this->fillField('login__password', $username);
  109. $this->pressButton('_submit');
  110. }
  111. /**
  112. * @Given /^I have a friend named "([^"]*)" with id "([^"]*)"$/
  113. */
  114. public function iHaveAFriend($friendUsername, $friendId)
  115. {
  116. $adminId = 1;
  117. $friendId = $friendId;
  118. $friendUsername = $friendUsername;
  119. $sendInvitationURL = '/main/inc/ajax/message.ajax.php?'.
  120. http_build_query(
  121. [
  122. 'a' => 'send_invitation',
  123. 'user_id' => $friendId,
  124. 'content' => 'Add me',
  125. ]
  126. );
  127. $acceptInvitationURL = '/main/inc/ajax/social.ajax.php?'.
  128. http_build_query(
  129. [
  130. 'a' => 'add_friend',
  131. 'friend_id' => $adminId,
  132. 'is_my_friend' => 'friend',
  133. ]
  134. );
  135. $this->iAmAPlatformAdministrator();
  136. $this->visit($sendInvitationURL);
  137. $this->iAmLoggedAs($friendUsername);
  138. $this->visit($acceptInvitationURL);
  139. $this->iAmAPlatformAdministrator();
  140. }
  141. /**
  142. * @Given /^I have a public password-protected course named "([^"]*)" with password "([^"]*)"$/
  143. */
  144. public function iHaveAPublicPasswordProtectedCourse($code, $password)
  145. {
  146. $this->visit('/main/admin/course_add.php');
  147. $this->fillFields(
  148. new TableNode(
  149. [
  150. ['title', 'Password Protected'],
  151. ['visual_code', $code],
  152. ['visibility', 3],
  153. ]
  154. )
  155. );
  156. $this->pressButton('submit');
  157. $this->visit('/main/course_info/infocours.php?cidReq='.$code);
  158. $this->assertPageContainsText('Course registration password');
  159. $this->fillField('course_registration_password', $password);
  160. $this->pressButton('submit_save');
  161. $this->assertFieldContains('course_registration_password', $password);
  162. }
  163. /**
  164. * @Given /^I am not logged$/
  165. */
  166. public function iAmNotLogged()
  167. {
  168. $this->visit('/index.php?logout=logout');
  169. $this->visit('I am on homepage');
  170. }
  171. /**
  172. * @When /^I invite to a friend with id "([^"]*)" to a social group with id "([^"]*)"$/
  173. */
  174. public function iInviteAFriendToASocialGroup($friendId, $groupId)
  175. {
  176. $this->visit('/main/social/group_invitation.php?id='.$groupId);
  177. $this->fillField('invitation[]', $friendId);
  178. $this->pressButton('submit');
  179. }
  180. /**
  181. * Sometimes the top admin toolbar has form buttons
  182. * that conflicts with the main page forms so we need
  183. * to disable it
  184. * @Given /^Admin top bar is disabled$/
  185. */
  186. public function adminTopBarIsDisabled()
  187. {
  188. $this->iAmAPlatformAdministrator();
  189. $this->visit('/main/admin/settings.php');
  190. $this->fillField('search_field', 'show_admin_toolbar');
  191. $this->pressButton('submit_button');
  192. $this->selectOption('show_admin_toolbar', 'do_not_show');
  193. $this->pressButton('submit');
  194. }
  195. /**
  196. * @Given /^Admin top bar is enabled$/
  197. */
  198. public function adminTopBarIsEnabled()
  199. {
  200. $this->iAmAPlatformAdministrator();
  201. $this->visit('/main/admin/settings.php');
  202. $this->fillField('search_field', 'show_admin_toolbar');
  203. $this->pressButton('submit_button');
  204. $this->selectOption('show_admin_toolbar', 'show_to_admin_and_teachers');
  205. $this->pressButton('submit');
  206. }
  207. /**
  208. * @Given /^I am on the social group members page with id "([^"]*)"$/
  209. */
  210. public function iAmOnSocialGroupMembersPageWithId($groupId)
  211. {
  212. $this->visit('/main/social/group_view.php?id='.$groupId);
  213. }
  214. /**
  215. * @When /^I try delete a friend with id "([^"]*)" from the social group with id "([^"]*)"$/
  216. */
  217. public function iTryDeleteAFriendFromSocialGroup($friendId, $groupId)
  218. {
  219. $this->visit(
  220. '/main/social/group_members.php?'.http_build_query(
  221. [
  222. 'id' => $groupId,
  223. 'u' => $friendId,
  224. 'action' => 'delete',
  225. ]
  226. )
  227. );
  228. }
  229. /**
  230. * @Then /^I fill in ckeditor field "([^"]*)" with "([^"]*)"$/
  231. */
  232. public function iFillInWysiwygOnFieldWith($locator, $value)
  233. {
  234. // Just in case wait that ckeditor is loaded
  235. $this->getSession()->wait(2000);
  236. $el = $this->getSession()->getPage()->findField($locator);
  237. $fieldId = $el->getAttribute('id');
  238. if (empty($fieldId)) {
  239. throw new Exception(
  240. 'Could not find an id for field with locator: '.$locator
  241. );
  242. }
  243. $this->getSession()->executeScript(
  244. "CKEDITOR.instances[\"$fieldId\"].setData(\"$value\");"
  245. );
  246. }
  247. /**
  248. * @Then /^I fill the only ckeditor in the page with "([^"]*)"$/
  249. */
  250. public function iFillTheOnlyEditorInThePage($value)
  251. {
  252. // Just in case wait that ckeditor is loaded
  253. $this->getSession()->wait(2000);
  254. $this->getSession()->executeScript(
  255. "
  256. var textarea = $('textarea');
  257. var id = textarea.attr('id');
  258. CKEDITOR.instances[id].setData(\"$value\");
  259. "
  260. );
  261. }
  262. /**
  263. * @Given /^I fill hidden field "([^"]*)" with "([^"]*)"$/
  264. */
  265. public function iFillHiddenFieldWith($field, $value)
  266. {
  267. $this->getSession()->getPage()->find(
  268. 'css',
  269. 'input[name="'.$field.'"]'
  270. )->setValue($value);
  271. }
  272. /**
  273. * @When /^(?:|I )fill in select2 input "(?P<field>(?:[^"]|\\")*)" with id "(?P<id>(?:[^"]|\\")*)" and value "(?P<value>(?:[^"]|\\")*)"$/
  274. */
  275. public function iFillInSelectInputWithAndSelect($field, $id, $value)
  276. {
  277. $this->getSession()->executeScript("$('$field').select2({data : [{id: $id, text: '$value'}]});");
  278. }
  279. /**
  280. * @When /^(?:|I )confirm the popup$/
  281. */
  282. public function confirmPopup()
  283. {
  284. // See
  285. // https://gist.github.com/blazarecki/2888851
  286. /** @var \Behat\Mink\Driver\Selenium2Driver $driver Needed because no cross-driver way yet */
  287. $this->getSession()->getDriver()->getWebDriverSession()->accept_alert();
  288. }
  289. /**
  290. * @When /^(?:|I )fill in select bootstrap input "(?P<field>(?:[^"]|\\")*)" with "(?P<value>(?:[^"]|\\")*)" and select "(?P<entry>(?:[^"]|\\")*)"$/
  291. */
  292. public function iFillInSelectBootstrapInputWithAndSelect($field, $value, $entry)
  293. {
  294. $page = $this->getSession()->getPage();
  295. $inputField = $page->find('css', $field);
  296. if (!$inputField) {
  297. throw new \Exception('No field found');
  298. }
  299. $choice = $inputField->getParent()->find('css', '.bootstrap-select');
  300. if (!$choice) {
  301. throw new \Exception('No select bootstrap choice found');
  302. }
  303. $choice->press();
  304. $selectInput = $inputField->getParent()->find('css', '.bootstrap-select .form-control');
  305. if (!$selectInput) {
  306. throw new \Exception('No input found');
  307. }
  308. $selectInput->setValue($value);
  309. $this->getSession()->wait(3000);
  310. $chosenResults = $inputField->getParent()->findAll('css', '.dropdown-menu inner li');
  311. foreach ($chosenResults as $result) {
  312. //$option = $result->find('css', '.text');
  313. if ($result->getText() == $entry) {
  314. $result->click();
  315. break;
  316. }
  317. }
  318. }
  319. /**
  320. * @When /^(?:|I )fill in select bootstrap static input "(?P<field>(?:[^"]|\\")*)" select "(?P<value>(?:[^"]|\\")*)"$/
  321. */
  322. public function iFillInSelectStaticBootstrapInputWithAndSelect($field, $value)
  323. {
  324. $this->getSession()->wait(1000);
  325. $this->getSession()->executeScript("
  326. $(function() {
  327. $('$field').selectpicker('val', '$value');
  328. });
  329. ");
  330. }
  331. /**
  332. * @When /^(?:|I )fill in select bootstrap static by text "(?P<field>(?:[^"]|\\")*)" select "(?P<value>(?:[^"]|\\")*)"$/
  333. */
  334. public function iFillInSelectStaticBootstrapInputWithAndSelectByText($field, $value)
  335. {
  336. $this->getSession()->wait(1000);
  337. $this->getSession()->executeScript("
  338. $('$field > option').each(function(index, option) {
  339. if (option.text == '$value') {
  340. $('$field').selectpicker('val', option.value);
  341. }
  342. });
  343. ");
  344. }
  345. /**
  346. * @When /^(?:|I )fill in select "(?P<field>(?:[^"]|\\")*)" with option value "(?P<value>(?:[^"]|\\")*)" with class "(?P<id>(?:[^"]|\\")*)"$/
  347. */
  348. public function iFillInSelectWithOptionValue($field, $value, $class)
  349. {
  350. $this->getSession()->wait(1000);
  351. $this->getSession()->executeScript("
  352. var input = $('$field').filter('$class');
  353. var id = input.attr('id');
  354. var input = $('#'+id);
  355. input.val($value);
  356. ");
  357. }
  358. /**
  359. * @When /^wait for the page to be loaded$/
  360. */
  361. public function waitForThePageToBeLoaded()
  362. {
  363. $this->getSession()->wait(3000);
  364. }
  365. /**
  366. * @When /^wait very long for the page to be loaded$/
  367. */
  368. public function waitVeryLongForThePageToBeLoaded()
  369. {
  370. //$this->getSession()->wait(10000, "document.readyState === 'complete'");
  371. $this->getSession()->wait(8000);
  372. }
  373. /**
  374. * @When /^I check the "([^"]*)" radio button$/
  375. */
  376. public function iCheckTheRadioButton($radioLabel)
  377. {
  378. $radioButton = $this->getSession()->getPage()->findField($radioLabel);
  379. if (null === $radioButton) {
  380. throw new Exception("Cannot find radio button ".$radioLabel);
  381. }
  382. //$value = $radioButton->getAttribute('value');
  383. $this->getSession()->getDriver()->click($radioButton->getXPath());
  384. }
  385. /**
  386. * @When /^I check radio button with label "([^"]*)"$/
  387. */
  388. public function iCheckTheRadioButtonWithLabel($label)
  389. {
  390. $this->getSession()->executeScript("
  391. $(function() {
  392. $(':contains(\$label\")').parent().find('input').prop('checked', true);
  393. });
  394. ");
  395. }
  396. /**
  397. * @When /^I press advanced settings$/
  398. */
  399. public function iSelectFromSelectWithLabel()
  400. {
  401. $this->pressButton('Advanced settings');
  402. }
  403. /**
  404. * Clicks link with specified id|title|alt|text
  405. * Example: When I follow "Log In"
  406. * Example: And I follow "Log In"
  407. *
  408. * @When /^(?:|I )focus "(?P<link>(?:[^"]|\\")*)"$/
  409. */
  410. public function focus($input)
  411. {
  412. $input = $this->getSession()->getPage()->findField($input);
  413. $input->focus();
  414. }
  415. /**
  416. * @Given /^I check the "([^"]*)" radio button with "([^"]*)" value$/
  417. */
  418. public function iCheckTheRadioButtonWithValue($element, $value)
  419. {
  420. $this->getSession()->executeScript("
  421. $(function() {
  422. $('input[type=\"radio\"][name=".$element."][value=".$value."]').prop('checked', true);
  423. });
  424. ");
  425. return true;
  426. }
  427. /**
  428. * @Then /^I should see an icon with title "([^"]*)"$/
  429. */
  430. public function iShouldSeeAnIconWithTitle($value)
  431. {
  432. $el = $this->getSession()->getPage()->find('xpath', "//img[@title='$value']");
  433. if (null === $el) {
  434. throw new Exception(
  435. 'Could not find an icon with title: '.$value
  436. );
  437. }
  438. return true;
  439. }
  440. /**
  441. * @Then /^I should not see an icon with title "([^"]*)"$/
  442. */
  443. public function iShouldNotSeeAnIconWithTitle($value)
  444. {
  445. $el = $this->getSession()->getPage()->find('xpath', "//img[@title='$value']");
  446. if (null === $el) {
  447. return true;
  448. }
  449. return false;
  450. }
  451. /**
  452. * @Then /^I save current URL with name "([^"]*)"$/
  453. */
  454. public function saveUrlWithName($name)
  455. {
  456. $url = $this->getSession()->getCurrentUrl();
  457. $this->getSession()->setCookie($name, $url);
  458. }
  459. /**
  460. * @Then /^I visit URL saved with name "([^"]*)"$/
  461. */
  462. public function visitSavedUrlWithName($name)
  463. {
  464. $url = $this->getSession()->getCookie($name);
  465. echo $url;
  466. if (empty($url)) {
  467. throw new Exception("Url with name: $name not found");
  468. }
  469. $this->visit($url);
  470. }
  471. /**
  472. * @Given /^I am a student subscribed to session "([^"]*)"$/
  473. *
  474. * @param string$sessionName
  475. */
  476. public function iAmStudentSubscribedToXSession($sessionName)
  477. {
  478. $this->iAmAPlatformAdministrator();
  479. $this->visit('/main/session/session_add.php');
  480. $this->fillField('name', $sessionName);
  481. $this->pressButton('Next step');
  482. $this->selectOption('NoSessionCoursesList[]', 'TEMP (TEMP)');
  483. $this->pressButton('add_course');
  484. $this->pressButton('Next step');
  485. $this->assertPageContainsText('Update successful');
  486. $this->fillField('user_to_add', 'acostea');
  487. $this->waitForThePageToBeLoaded();
  488. $this->clickLink('Costea Andrea (acostea)');
  489. $this->pressButton('Finish session creation');
  490. $this->assertPageContainsText('Session overview');
  491. //$this->assertPageContainsText('Costea Andrea (acostea)');
  492. $this->iAmAStudent();
  493. }
  494. /**
  495. * Example: Then I should see the table "#category_results":
  496. * | Categories | Absolute score | Relative score |
  497. * | Categoryname2 | 50 / 70 | 71.43% |
  498. * | Categoryname1 | 60 / 60 | 100% |
  499. *
  500. * @Then /^I should see the table "([^"]*)":$/
  501. *
  502. * @param string $tableId
  503. * @param TableNode $tableData
  504. *
  505. * @throws Exception
  506. */
  507. public function assertPageContainsTable($tableId, TableNode $tableData)
  508. {
  509. $table = $this->getSession()->getPage()->find('css', $tableId);
  510. $rows = $tableData->getRowsHash();
  511. $i = 1;
  512. $right = array_keys($rows);
  513. foreach ($right as $text) {
  514. $cell = $table->find('css', 'tr:nth-child('.$i.') :nth-child(1)');
  515. $i++;
  516. if (!$cell) {
  517. throw new Exception('Cell not found.');
  518. }
  519. if ($cell->getText() != $text) {
  520. throw new Exception('Table text not found.');
  521. }
  522. }
  523. $i = 1;
  524. foreach ($rows as $field => $cols) {
  525. if (is_array($cols)) {
  526. $j = 2;
  527. foreach ($cols as $col) {
  528. $cell = $table->find('css', 'tr:nth-child('.$i.') :nth-child('.$j.')');
  529. $j++;
  530. if (!$cell) {
  531. throw new Exception('Cell not found.');
  532. }
  533. if ($cell->getText() != $col) {
  534. throw new Exception('Table text not found. Found "'.$cell->getText().'" <> "'.$col.'"');
  535. }
  536. }
  537. } else {
  538. $cell = $table->find('css', 'tr:nth-child('.$i.') :nth-child(2)');
  539. if (!$cell) {
  540. throw new Exception('Cell not found.');
  541. }
  542. if ($cell->getText() != $cols) {
  543. throw new Exception('Table text not found. Found "'.$cell->getText().'" <> "'.$cols.'"');
  544. }
  545. }
  546. $i++;
  547. }
  548. }
  549. }