[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Steps definitions related to mod_quiz. 19 * 20 * @package mod_quiz 21 * @category test 22 * @copyright 2014 Marina Glancy 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. 27 28 require_once (__DIR__ . '/../../../../lib/behat/behat_base.php'); 29 require_once (__DIR__ . '/../../../../question/tests/behat/behat_question_base.php'); 30 31 use Behat\Gherkin\Node\TableNode as TableNode; 32 33 use Behat\Mink\Exception\ExpectationException as ExpectationException; 34 35 /** 36 * Steps definitions related to mod_quiz. 37 * 38 * @copyright 2014 Marina Glancy 39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 40 */ 41 class behat_mod_quiz extends behat_question_base { 42 43 /** 44 * Put the specified questions on the specified pages of a given quiz. 45 * 46 * The first row should be column names: 47 * | question | page | maxmark | requireprevious | 48 * The first two of those are required. The others are optional. 49 * 50 * question needs to uniquely match a question name. 51 * page is a page number. Must start at 1, and on each following 52 * row should be the same as the previous, or one more. 53 * maxmark What the question is marked out of. Defaults to question.defaultmark. 54 * requireprevious The question can only be attempted after the previous one was completed. 55 * 56 * Then there should be a number of rows of data, one for each question you want to add. 57 * 58 * For backwards-compatibility reasons, specifying the column names is optional 59 * (but strongly encouraged). If not specified, the columns are asseumed to be 60 * | question | page | maxmark |. 61 * 62 * @param string $quizname the name of the quiz to add questions to. 63 * @param TableNode $data information about the questions to add. 64 * 65 * @Given /^quiz "([^"]*)" contains the following questions:$/ 66 */ 67 public function quiz_contains_the_following_questions($quizname, TableNode $data) { 68 global $DB; 69 70 $quiz = $DB->get_record('quiz', array('name' => $quizname), '*', MUST_EXIST); 71 72 // Deal with backwards-compatibility, optional first row. 73 $firstrow = $data->getRow(0); 74 if (!in_array('question', $firstrow) && !in_array('page', $firstrow)) { 75 if (count($firstrow) == 2) { 76 $headings = array('question', 'page'); 77 } else if (count($firstrow) == 3) { 78 $headings = array('question', 'page', 'maxmark'); 79 } else { 80 throw new ExpectationException('When adding questions to a quiz, you should give 2 or three 3 things: ' . 81 ' the question name, the page number, and optionally the maxiumum mark. ' . 82 count($firstrow) . ' values passed.', $this->getSession()); 83 } 84 $rows = $data->getRows(); 85 array_unshift($rows, $headings); 86 $data = new TableNode($rows); 87 } 88 89 // Add the questions. 90 $lastpage = 0; 91 foreach ($data->getHash() as $questiondata) { 92 if (!array_key_exists('question', $questiondata)) { 93 throw new ExpectationException('When adding questions to a quiz, ' . 94 'the question name column is required.', $this->getSession()); 95 } 96 if (!array_key_exists('page', $questiondata)) { 97 throw new ExpectationException('When adding questions to a quiz, ' . 98 'the page number column is required.', $this->getSession()); 99 } 100 101 // Question id. 102 $questionid = $DB->get_field('question', 'id', 103 array('name' => $questiondata['question']), MUST_EXIST); 104 105 // Page number. 106 $page = clean_param($questiondata['page'], PARAM_INT); 107 if ($page <= 0 || (string) $page !== $questiondata['page']) { 108 throw new ExpectationException('The page number for question "' . 109 $questiondata['question'] . '" must be a positive integer.', 110 $this->getSession()); 111 } 112 if ($page < $lastpage || $page > $lastpage + 1) { 113 throw new ExpectationException('When adding questions to a quiz, ' . 114 'the page number for each question must either be the same, ' . 115 'or one more, then the page number for the previous question.', 116 $this->getSession()); 117 } 118 $lastpage = $page; 119 120 // Max mark. 121 if (!array_key_exists('maxmark', $questiondata) || $questiondata['maxmark'] === '') { 122 $maxmark = null; 123 } else { 124 $maxmark = clean_param($questiondata['maxmark'], PARAM_FLOAT); 125 if (!is_numeric($questiondata['maxmark']) || $maxmark < 0) { 126 throw new ExpectationException('The max mark for question "' . 127 $questiondata['question'] . '" must be a positive number.', 128 $this->getSession()); 129 } 130 } 131 132 // Add the question. 133 quiz_add_quiz_question($questionid, $quiz, $page, $maxmark); 134 135 // Require previous. 136 if (array_key_exists('requireprevious', $questiondata)) { 137 if ($questiondata['requireprevious'] === '1') { 138 $slot = $DB->get_field('quiz_slots', 'MAX(slot)', array('quizid' => $quiz->id)); 139 $DB->set_field('quiz_slots', 'requireprevious', 1, 140 array('quizid' => $quiz->id, 'slot' => $slot)); 141 } else if ($questiondata['requireprevious'] !== '' && $questiondata['requireprevious'] !== '0') { 142 throw new ExpectationException('Require previous for question "' . 143 $questiondata['question'] . '" should be 0, 1 or blank.', 144 $this->getSession()); 145 } 146 } 147 } 148 149 quiz_update_sumgrades($quiz); 150 } 151 152 /** 153 * Put the specified section headings to start at specified pages of a given quiz. 154 * 155 * The first row should be column names: 156 * | heading | firstslot | shufflequestions | 157 * 158 * heading is the section heading text 159 * firstslot is the slot number where the section starts 160 * shuffle whether this section is shuffled (0 or 1) 161 * 162 * Then there should be a number of rows of data, one for each section you want to add. 163 * 164 * @param string $quizname the name of the quiz to add sections to. 165 * @param TableNode $data information about the sections to add. 166 * 167 * @Given /^quiz "([^"]*)" contains the following sections:$/ 168 */ 169 public function quiz_contains_the_following_sections($quizname, TableNode $data) { 170 global $DB; 171 172 $quiz = $DB->get_record('quiz', array('name' => $quizname), '*', MUST_EXIST); 173 174 // Add the sections. 175 $previousfirstslot = 0; 176 foreach ($data->getHash() as $rownumber => $sectiondata) { 177 if (!array_key_exists('heading', $sectiondata)) { 178 throw new ExpectationException('When adding sections to a quiz, ' . 179 'the heading name column is required.', $this->getSession()); 180 } 181 if (!array_key_exists('firstslot', $sectiondata)) { 182 throw new ExpectationException('When adding sections to a quiz, ' . 183 'the firstslot name column is required.', $this->getSession()); 184 } 185 if (!array_key_exists('shuffle', $sectiondata)) { 186 throw new ExpectationException('When adding sections to a quiz, ' . 187 'the shuffle name column is required.', $this->getSession()); 188 } 189 190 if ($rownumber == 0) { 191 $section = $DB->get_record('quiz_sections', array('quizid' => $quiz->id), '*', MUST_EXIST); 192 } else { 193 $section = new stdClass(); 194 $section->quizid = $quiz->id; 195 } 196 197 // Heading. 198 $section->heading = $sectiondata['heading']; 199 200 // First slot. 201 $section->firstslot = clean_param($sectiondata['firstslot'], PARAM_INT); 202 if ($section->firstslot <= $previousfirstslot || 203 (string) $section->firstslot !== $sectiondata['firstslot']) { 204 throw new ExpectationException('The firstslot number for section "' . 205 $sectiondata['heading'] . '" must an integer greater than the previous section firstslot.', 206 $this->getSession()); 207 } 208 if ($rownumber == 0 && $section->firstslot != 1) { 209 throw new ExpectationException('The first section must have firstslot set to 1.', 210 $this->getSession()); 211 } 212 213 // Shuffle. 214 $section->shufflequestions = clean_param($sectiondata['shuffle'], PARAM_INT); 215 if ((string) $section->shufflequestions !== $sectiondata['shuffle']) { 216 throw new ExpectationException('The shuffle value for section "' . 217 $sectiondata['heading'] . '" must be 0 or 1.', 218 $this->getSession()); 219 } 220 221 if ($rownumber == 0) { 222 $DB->update_record('quiz_sections', $section); 223 } else { 224 $DB->insert_record('quiz_sections', $section); 225 } 226 } 227 228 if ($section->firstslot > $DB->count_records('quiz_slots', array('quizid' => $quiz->id))) { 229 throw new ExpectationException('The section firstslot must be less than the total number of slots in the quiz.', 230 $this->getSession()); 231 } 232 } 233 234 /** 235 * Adds a question to the existing quiz with filling the form. 236 * 237 * The form for creating a question should be on one page. 238 * 239 * @When /^I add a "(?P<question_type_string>(?:[^"]|\\")*)" question to the "(?P<quiz_name_string>(?:[^"]|\\")*)" quiz with:$/ 240 * @param string $questiontype 241 * @param string $quizname 242 * @param TableNode $questiondata with data for filling the add question form 243 */ 244 public function i_add_question_to_the_quiz_with($questiontype, $quizname, TableNode $questiondata) { 245 $quizname = $this->escape($quizname); 246 $editquiz = $this->escape(get_string('editquiz', 'quiz')); 247 $quizadmin = $this->escape(get_string('pluginadministration', 'quiz')); 248 $addaquestion = $this->escape(get_string('addaquestion', 'quiz')); 249 $menuxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' textmenu')]"; 250 $itemxpath = "//div[contains(@class, ' page-add-actions ')][last()]//a[contains(@class, ' addquestion ')]"; 251 252 $this->execute('behat_general::click_link', $quizname); 253 254 $this->execute("behat_navigation::i_navigate_to_node_in", array($editquiz, $quizadmin)); 255 256 $this->execute("behat_general::i_click_on", array($menuxpath, "xpath_element")); 257 $this->execute("behat_general::i_click_on", array($itemxpath, "xpath_element")); 258 259 $this->finish_adding_question($questiontype, $questiondata); 260 } 261 262 /** 263 * Set the max mark for a question on the Edit quiz page. 264 * 265 * @When /^I set the max mark for question "(?P<question_name_string>(?:[^"]|\\")*)" to "(?P<new_mark_string>(?:[^"]|\\")*)"$/ 266 * @param string $questionname the name of the question to set the max mark for. 267 * @param string $newmark the mark to set 268 */ 269 public function i_set_the_max_mark_for_quiz_question($questionname, $newmark) { 270 $this->execute('behat_general::click_link', $this->escape(get_string('editmaxmark', 'quiz'))); 271 272 $this->execute('behat_general::wait_until_exists', array("li input[name=maxmark]", "css_element")); 273 274 $this->execute('behat_general::assert_page_contains_text', $this->escape(get_string('edittitleinstructions'))); 275 276 $this->execute('behat_forms::i_set_the_field_to', array('maxmark', $this->escape($newmark) . chr(10))); 277 } 278 279 /** 280 * Open the add menu on a given page, or at the end of the Edit quiz page. 281 * @Given /^I open the "(?P<page_n_or_last_string>(?:[^"]|\\")*)" add to quiz menu$/ 282 * @param string $pageorlast either "Page n" or "last". 283 */ 284 public function i_open_the_add_to_quiz_menu_for($pageorlast) { 285 286 if (!$this->running_javascript()) { 287 throw new DriverException('Activities actions menu not available when Javascript is disabled'); 288 } 289 290 if ($pageorlast == 'last') { 291 $xpath = "//div[@class = 'last-add-menu']//a[contains(@class, 'textmenu') and contains(., 'Add')]"; 292 } else if (preg_match('~Page (\d+)~', $pageorlast, $matches)) { 293 $xpath = "//li[@id = 'page-{$matches[1]}']//a[contains(@class, 'textmenu') and contains(., 'Add')]"; 294 } else { 295 throw new ExpectationException("The I open the add to quiz menu step must specify either 'Page N' or 'last'."); 296 } 297 $this->find('xpath', $xpath)->click(); 298 } 299 300 /** 301 * Click on a given link in the moodle-actionmenu that is currently open. 302 * @Given /^I follow "(?P<link_string>(?:[^"]|\\")*)" in the open menu$/ 303 * @param string $linkstring the text (or id, etc.) of the link to click. 304 */ 305 public function i_follow_in_the_open_menu($linkstring) { 306 $openmenuxpath = "//div[contains(@class, 'moodle-actionmenu') and contains(@class, 'show')]"; 307 308 $this->execute('behat_general::i_click_on_in_the', 309 array($linkstring, "link", $openmenuxpath, "xpath_element") 310 ); 311 312 } 313 314 /** 315 * Check whether a particular question is on a particular page of the quiz on the Edit quiz page. 316 * @Given /^I should see "(?P<question_name>(?:[^"]|\\")*)" on quiz page "(?P<page_number>\d+)"$/ 317 * @param string $questionname the name of the question we are looking for. 318 * @param number $pagenumber the page it should be found on. 319 */ 320 public function i_should_see_on_quiz_page($questionname, $pagenumber) { 321 $xpath = "//li[contains(., '" . $this->escape($questionname) . 322 "')][./preceding-sibling::li[contains(@class, 'pagenumber')][1][contains(., 'Page " . 323 $pagenumber . "')]]"; 324 325 $this->execute('behat_general::should_exist', array($xpath, 'xpath_element')); 326 } 327 328 /** 329 * Check whether a particular question is not on a particular page of the quiz on the Edit quiz page. 330 * @Given /^I should not see "(?P<question_name>(?:[^"]|\\")*)" on quiz page "(?P<page_number>\d+)"$/ 331 * @param string $questionname the name of the question we are looking for. 332 * @param number $pagenumber the page it should be found on. 333 */ 334 public function i_should_not_see_on_quiz_page($questionname, $pagenumber) { 335 $xpath = "//li[contains(., '" . $this->escape($questionname) . 336 "')][./preceding-sibling::li[contains(@class, 'pagenumber')][1][contains(., 'Page " . 337 $pagenumber . "')]]"; 338 339 $this->execute('behat_general::should_not_exist', array($xpath, 'xpath_element')); 340 } 341 342 /** 343 * Check whether one question comes before another on the Edit quiz page. 344 * The two questions must be on the same page. 345 * @Given /^I should see "(?P<first_q_name>(?:[^"]|\\")*)" before "(?P<second_q_name>(?:[^"]|\\")*)" on the edit quiz page$/ 346 * @param string $firstquestionname the name of the question that should come first in order. 347 * @param string $secondquestionname the name of the question that should come immediately after it in order. 348 */ 349 public function i_should_see_before_on_the_edit_quiz_page($firstquestionname, $secondquestionname) { 350 $xpath = "//li[contains(@class, ' slot ') and contains(., '" . $this->escape($firstquestionname) . 351 "')]/following-sibling::li[contains(@class, ' slot ')][1]" . 352 "[contains(., '" . $this->escape($secondquestionname) . "')]"; 353 354 $this->execute('behat_general::should_exist', array($xpath, 'xpath_element')); 355 } 356 357 /** 358 * Check the number displayed alongside a question on the Edit quiz page. 359 * @Given /^"(?P<question_name>(?:[^"]|\\")*)" should have number "(?P<number>(?:[^"]|\\")*)" on the edit quiz page$/ 360 * @param string $questionname the name of the question we are looking for. 361 * @param number $number the number (or 'i') that should be displayed beside that question. 362 */ 363 public function should_have_number_on_the_edit_quiz_page($questionname, $number) { 364 $xpath = "//li[contains(@class, 'slot') and contains(., '" . $this->escape($questionname) . 365 "')]//span[contains(@class, 'slotnumber') and normalize-space(text()) = '" . $this->escape($number) . "']"; 366 367 $this->execute('behat_general::should_exist', array($xpath, 'xpath_element')); 368 } 369 370 /** 371 * Get the xpath for a partcular add/remove page-break icon. 372 * @param string $addorremoves 'Add' or 'Remove'. 373 * @param string $questionname the name of the question before the icon. 374 * @return string the requried xpath. 375 */ 376 protected function get_xpath_page_break_icon_after_question($addorremoves, $questionname) { 377 return "//li[contains(@class, 'slot') and contains(., '" . $this->escape($questionname) . 378 "')]//a[contains(@class, 'page_split_join') and @title = '" . $addorremoves . " page break']"; 379 } 380 381 /** 382 * Click the add or remove page-break icon after a particular question. 383 * @When /^I click on the "(Add|Remove)" page break icon after question "(?P<question_name>(?:[^"]|\\")*)"$/ 384 * @param string $addorremoves 'Add' or 'Remove'. 385 * @param string $questionname the name of the question before the icon to click. 386 */ 387 public function i_click_on_the_page_break_icon_after_question($addorremoves, $questionname) { 388 $xpath = $this->get_xpath_page_break_icon_after_question($addorremoves, $questionname); 389 390 $this->execute("behat_general::i_click_on", array($xpath, "xpath_element")); 391 } 392 393 /** 394 * Assert the add or remove page-break icon after a particular question exists. 395 * @When /^the "(Add|Remove)" page break icon after question "(?P<question_name>(?:[^"]|\\")*)" should exist$/ 396 * @param string $addorremoves 'Add' or 'Remove'. 397 * @param string $questionname the name of the question before the icon to click. 398 * @return array of steps. 399 */ 400 public function the_page_break_icon_after_question_should_exist($addorremoves, $questionname) { 401 $xpath = $this->get_xpath_page_break_icon_after_question($addorremoves, $questionname); 402 403 $this->execute('behat_general::should_exist', array($xpath, 'xpath_element')); 404 } 405 406 /** 407 * Assert the add or remove page-break icon after a particular question does not exist. 408 * @When /^the "(Add|Remove)" page break icon after question "(?P<question_name>(?:[^"]|\\")*)" should not exist$/ 409 * @param string $addorremoves 'Add' or 'Remove'. 410 * @param string $questionname the name of the question before the icon to click. 411 * @return array of steps. 412 */ 413 public function the_page_break_icon_after_question_should_not_exist($addorremoves, $questionname) { 414 $xpath = $this->get_xpath_page_break_icon_after_question($addorremoves, $questionname); 415 416 $this->execute('behat_general::should_not_exist', array($xpath, 'xpath_element')); 417 } 418 419 /** 420 * Check the add or remove page-break link after a particular question contains the given parameters in its url. 421 * @When /^the "(Add|Remove)" page break link after question "(?P<question_name>(?:[^"]|\\")*) should contain:"$/ 422 * @param string $addorremoves 'Add' or 'Remove'. 423 * @param string $questionname the name of the question before the icon to click. 424 * @param TableNode $paramdata with data for checking the page break url 425 * @return array of steps. 426 */ 427 public function the_page_break_link_after_question_should_contain($addorremoves, $questionname, $paramdata) { 428 $xpath = $this->get_xpath_page_break_icon_after_question($addorremoves, $questionname); 429 430 $this->execute("behat_general::i_click_on", array($xpath, "xpath_element")); 431 } 432 433 /** 434 * Set Shuffle for shuffling questions within sections 435 * 436 * @param string $heading the heading of the section to change shuffle for. 437 * 438 * @Given /^I click on shuffle for section "([^"]*)" on the quiz edit page$/ 439 */ 440 public function i_click_on_shuffle_for_section($heading) { 441 $xpath = $this->get_xpath_for_shuffle_checkbox($heading); 442 $checkbox = $this->find('xpath', $xpath); 443 $this->ensure_node_is_visible($checkbox); 444 $checkbox->click(); 445 } 446 447 /** 448 * Check the shuffle checkbox for a particular section. 449 * 450 * @param string $heading the heading of the section to check shuffle for 451 * @param int $value whether the shuffle checkbox should be on or off. 452 * 453 * @Given /^shuffle for section "([^"]*)" should be "(On|Off)" on the quiz edit page$/ 454 */ 455 public function shuffle_for_section_should_be($heading, $value) { 456 $xpath = $this->get_xpath_for_shuffle_checkbox($heading); 457 $checkbox = $this->find('xpath', $xpath); 458 $this->ensure_node_is_visible($checkbox); 459 if ($value == 'On' && !$checkbox->isChecked()) { 460 $msg = "Shuffle for section '$heading' is not checked, but you are expecting it to be checked ($value). " . 461 "Check the line with: \nshuffle for section \"$heading\" should be \"$value\" on the quiz edit page" . 462 "\nin your behat script"; 463 throw new ExpectationException($msg, $this->getSession()); 464 } else if ($value == 'Off' && $checkbox->isChecked()) { 465 $msg = "Shuffle for section '$heading' is checked, but you are expecting it not to be ($value). " . 466 "Check the line with: \nshuffle for section \"$heading\" should be \"$value\" on the quiz edit page" . 467 "\nin your behat script"; 468 throw new ExpectationException($msg, $this->getSession()); 469 } 470 } 471 472 /** 473 * Return the xpath for shuffle checkbox in section heading 474 * @param string $heading 475 * @return string 476 */ 477 protected function get_xpath_for_shuffle_checkbox($heading) { 478 return "//div[contains(@class, 'section-heading') and contains(., '" . $this->escape($heading) . 479 "')]//input[@type = 'checkbox']"; 480 } 481 482 /** 483 * Move a question on the Edit quiz page by first clicking on the Move icon, 484 * then clicking one of the "After ..." links. 485 * @When /^I move "(?P<question_name>(?:[^"]|\\")*)" to "(?P<target>(?:[^"]|\\")*)" in the quiz by clicking the move icon$/ 486 * @param string $questionname the name of the question we are looking for. 487 * @param string $target the target place to move to. One of the links in the pop-up like 488 * "After Page 1" or "After Question N". 489 */ 490 public function i_move_question_after_item_by_clicking_the_move_icon($questionname, $target) { 491 $iconxpath = "//li[contains(@class, ' slot ') and contains(., '" . $this->escape($questionname) . 492 "')]//span[contains(@class, 'editing_move')]"; 493 494 $this->execute("behat_general::i_click_on", array($iconxpath, "xpath_element")); 495 $this->execute("behat_general::i_click_on", array($this->escape($target), "text")); 496 } 497 498 /** 499 * Move a question on the Edit quiz page by dragging a given question on top of another item. 500 * @When /^I move "(?P<question_name>(?:[^"]|\\")*)" to "(?P<target>(?:[^"]|\\")*)" in the quiz by dragging$/ 501 * @param string $questionname the name of the question we are looking for. 502 * @param string $target the target place to move to. Ether a question name, or "Page N" 503 */ 504 public function i_move_question_after_item_by_dragging($questionname, $target) { 505 $iconxpath = "//li[contains(@class, ' slot ') and contains(., '" . $this->escape($questionname) . 506 "')]//span[contains(@class, 'editing_move')]//img"; 507 $destinationxpath = "//li[contains(@class, ' slot ') or contains(@class, 'pagenumber ')]" . 508 "[contains(., '" . $this->escape($target) . "')]"; 509 510 $this->execute('behat_general::i_drag_and_i_drop_it_in', 511 array($iconxpath, 'xpath_element', $destinationxpath, 'xpath_element') 512 ); 513 } 514 515 /** 516 * Delete a question on the Edit quiz page by first clicking on the Delete icon, 517 * then clicking one of the "After ..." links. 518 * @When /^I delete "(?P<question_name>(?:[^"]|\\")*)" in the quiz by clicking the delete icon$/ 519 * @param string $questionname the name of the question we are looking for. 520 * @return array of steps. 521 */ 522 public function i_delete_question_by_clicking_the_delete_icon($questionname) { 523 $slotxpath = "//li[contains(@class, ' slot ') and contains(., '" . $this->escape($questionname) . 524 "')]"; 525 $deletexpath = "//a[contains(@class, 'editing_delete')]"; 526 527 $this->execute("behat_general::i_click_on", array($slotxpath . $deletexpath, "xpath_element")); 528 529 $this->execute('behat_general::i_click_on_in_the', 530 array('Yes', "button", "Confirm", "dialogue") 531 ); 532 } 533 534 /** 535 * Set the section heading for a given section on the Edit quiz page 536 * 537 * @When /^I change quiz section heading "(?P<section_name_string>(?:[^"]|\\")*)" to "(?P<new_section_heading_string>(?:[^"]|\\")*)"$/ 538 * @param string $sectionname the heading to change. 539 * @param string $sectionheading the new heading to set. 540 */ 541 public function i_set_the_section_heading_for($sectionname, $sectionheading) { 542 $this->execute('behat_general::click_link', $this->escape("Edit heading '{$sectionname}'")); 543 544 $this->execute('behat_general::assert_page_contains_text', $this->escape(get_string('edittitleinstructions'))); 545 546 $this->execute('behat_forms::i_set_the_field_to', array('section', $this->escape($sectionheading) . chr(10))); 547 } 548 549 /** 550 * Check that a given question comes after a given section heading in the 551 * quiz navigation block. 552 * 553 * @Then /^I should see question "(?P<questionnumber>\d+)" in section "(?P<section_heading_string>(?:[^"]|\\")*)" in the quiz navigation$/ 554 * @param int $questionnumber the number of the question to check. 555 * @param string $sectionheading which section heading it should appear after. 556 */ 557 public function i_should_see_question_in_section_in_the_quiz_navigation($questionnumber, $sectionheading) { 558 559 // Using xpath literal to avoid quotes problems. 560 $questionnumberliteral = behat_context_helper::escape('Question ' . $questionnumber); 561 $headingliteral = behat_context_helper::escape($sectionheading); 562 563 // Split in two checkings to give more feedback in case of exception. 564 $exception = new ExpectationException('Question "' . $questionnumber . '" is not in section "' . 565 $sectionheading . '" in the quiz navigation.', $this->getSession()); 566 $xpath = "//div[@id = 'mod_quiz_navblock']//*[contains(concat(' ', normalize-space(@class), ' '), ' qnbutton ') and " . 567 "contains(., {$questionnumberliteral}) and contains(preceding-sibling::h3[1], {$headingliteral})]"; 568 $this->find('xpath', $xpath); 569 } 570 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |