[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/quiz/tests/behat/ -> behat_mod_quiz.php (source)

   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  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1