Differences Between: [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]
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 * Backup and restore actions to help behat feature files writting. 19 * 20 * @package core_backup 21 * @category test 22 * @copyright 2013 David MonllaĆ³ 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__ . '/../../../../../lib/behat/behat_field_manager.php'); 30 require_once (__DIR__ . '/../../../../../lib/tests/behat/behat_navigation.php'); 31 32 use Behat\Gherkin\Node\TableNode as TableNode, 33 Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException, 34 Behat\Mink\Exception\ExpectationException as ExpectationException; 35 36 /** 37 * Backup-related steps definitions. 38 * 39 * @package core_backup 40 * @category test 41 * @copyright 2013 David MonllaĆ³ 42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 43 */ 44 class behat_backup extends behat_base { 45 46 /** 47 * Backups the specified course using the provided options. If you are interested in restoring this backup would be 48 * useful to provide a 'Filename' option. 49 * 50 * @Given /^I backup "(?P<course_fullname_string>(?:[^"]|\\")*)" course using this options:$/ 51 * @param string $backupcourse 52 * @param TableNode $options Backup options or false if no options provided 53 */ 54 public function i_backup_course_using_this_options($backupcourse, $options = false) { 55 // We can not use other steps here as we don't know where the provided data 56 // table elements are used, and we need to catch exceptions contantly. 57 58 // Go to homepage. 59 $this->execute('behat_general::i_visit', ['/?redirect=0']); 60 $this->execute("behat_general::wait_until_the_page_is_ready"); 61 62 // Click the course link. 63 $this->execute("behat_general::click_link", $backupcourse); 64 65 // Click the backup link. 66 $this->execute("behat_navigation::i_navigate_to_in_current_page_administration", get_string('backup')); 67 68 // Initial settings. 69 $this->fill_backup_restore_form($this->get_step_options($options, "Initial")); 70 $this->execute("behat_forms::press_button", get_string('backupstage1action', 'backup')); 71 72 // Schema settings. 73 $this->fill_backup_restore_form($this->get_step_options($options, "Schema")); 74 $this->execute("behat_forms::press_button", get_string('backupstage2action', 'backup')); 75 76 // Confirmation and review, backup filename can also be specified. 77 $this->fill_backup_restore_form($this->get_step_options($options, "Confirmation")); 78 $this->execute("behat_forms::press_button", get_string('backupstage4action', 'backup')); 79 80 // Waiting for it to finish. 81 $this->execute("behat_general::wait_until_the_page_is_ready"); 82 83 // Last backup continue button. 84 $this->execute("behat_general::i_click_on", array(get_string('backupstage16action', 'backup'), 'button')); 85 } 86 87 /** 88 * Performs a quick (one click) backup of a course. 89 * 90 * Please note that because you can't set settings with this there is no way to know what the filename 91 * that was produced was. It contains a timestamp making it hard to find. 92 * 93 * @Given /^I perform a quick backup of course "(?P<course_fullname_string>(?:[^"]|\\")*)"$/ 94 * @param string $backupcourse 95 */ 96 public function i_perform_a_quick_backup_of_course($backupcourse) { 97 // We can not use other steps here as we don't know where the provided data 98 // table elements are used, and we need to catch exceptions contantly. 99 100 // Go to homepage. 101 $this->execute('behat_general::i_visit', ['/?redirect=0']); 102 103 // Click the course link. 104 $this->execute("behat_general::click_link", $backupcourse); 105 106 // Click the backup link. 107 $this->execute("behat_navigation::i_navigate_to_in_current_page_administration", get_string('backup')); 108 109 // Initial settings. 110 $this->execute("behat_forms::press_button", get_string('jumptofinalstep', 'backup')); 111 112 // Waiting for it to finish. 113 $this->execute("behat_general::wait_until_the_page_is_ready"); 114 115 // Last backup continue button. 116 $this->execute("behat_general::i_click_on", array(get_string('backupstage16action', 'backup'), 'button')); 117 } 118 119 /** 120 * Imports the specified origin course into the other course using the provided options. 121 * 122 * Keeping it separatelly from backup & restore, it the number of 123 * steps and duplicate code becomes bigger a common method should 124 * be generalized. 125 * 126 * @Given /^I import "(?P<from_course_fullname_string>(?:[^"]|\\")*)" course into "(?P<to_course_fullname_string>(?:[^"]|\\")*)" course using this options:$/ 127 * @param string $fromcourse 128 * @param string $tocourse 129 * @param TableNode $options 130 */ 131 public function i_import_course_into_course($fromcourse, $tocourse, $options = false) { 132 133 // We can not use other steps here as we don't know where the provided data 134 // table elements are used, and we need to catch exceptions contantly. 135 136 // Go to homepage. 137 $this->execute('behat_general::i_visit', ['/?redirect=0']); 138 $this->execute("behat_general::wait_until_the_page_is_ready"); 139 140 // Click the course link. 141 $this->execute("behat_general::click_link", $tocourse); 142 143 // Click the import link. 144 $this->execute("behat_navigation::i_navigate_to_in_current_page_administration", get_string('import')); 145 146 // Select the course. 147 $fromcourse = behat_context_helper::escape($fromcourse); 148 $xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' ics-results ')]" . 149 "/descendant::tr[contains(., $fromcourse)]" . 150 "/descendant::input[@type='radio']"; 151 $this->execute('behat_forms::i_set_the_field_with_xpath_to', [$xpath, 1]); 152 153 $this->execute("behat_forms::press_button", get_string('continue')); 154 155 // Initial settings. 156 $this->fill_backup_restore_form($this->get_step_options($options, "Initial")); 157 $this->execute("behat_forms::press_button", get_string('importbackupstage1action', 'backup')); 158 159 // Schema settings. 160 $this->fill_backup_restore_form($this->get_step_options($options, "Schema")); 161 $this->execute("behat_forms::press_button", get_string('importbackupstage2action', 'backup')); 162 163 // Run it. 164 $this->execute("behat_forms::press_button", get_string('importbackupstage4action', 'backup')); 165 166 // Wait to ensure restore is complete. 167 $this->execute("behat_general::wait_until_the_page_is_ready"); 168 169 // Continue and redirect to 'to' course. 170 $this->execute("behat_general::i_click_on", array(get_string('continue'), 'button')); 171 } 172 173 /** 174 * Restores the backup into the specified course and the provided options. 175 * 176 * You should be in the 'Restore' page where the backup is. 177 * 178 * @Given /^I restore "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into "(?P<existing_course_fullname_string>(?:[^"]|\\")*)" course using this options:$/ 179 * @param string $backupfilename 180 * @param string $existingcourse 181 * @param TableNode $options Restore forms options or false if no options provided 182 */ 183 public function i_restore_backup_into_course_using_this_options($backupfilename, $existingcourse, $options = false) { 184 185 // Confirm restore. 186 $this->select_backup($backupfilename); 187 188 // The argument should be converted to an xpath literal. 189 $existingcourse = behat_context_helper::escape($existingcourse); 190 191 // Selecting the specified course (we can not call behat_forms::select_radio here as is in another behat subcontext). 192 $radionodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' bcs-existing-course ')]" . 193 "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' restore-course-search ')]" . 194 "/descendant::tr[contains(., $existingcourse)]" . 195 "/descendant::input[@type='radio']"; 196 $this->execute("behat_general::i_click_on", array($radionodexpath, 'xpath_element')); 197 198 // Pressing the continue button of the restore into an existing course section. 199 $continuenodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' bcs-existing-course ')]" . 200 "/descendant::input[@type='submit'][@value='" . get_string('continue') . "']"; 201 $this->execute("behat_general::i_click_on", array($continuenodexpath, 'xpath_element')); 202 203 // Common restore process using provided key/value options. 204 $this->process_restore($options); 205 } 206 207 /** 208 * Restores the specified backup into a new course using the provided options. 209 * 210 * You should be in the 'Restore' page where the backup is. 211 * 212 * @Given /^I restore "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into a new course using this options:$/ 213 * @param string $backupfilename 214 * @param TableNode $options Restore forms options or false if no options provided 215 */ 216 public function i_restore_backup_into_a_new_course_using_this_options($backupfilename, $options = false) { 217 218 // Confirm restore. 219 $this->select_backup($backupfilename); 220 221 // The first category in the list. 222 $radionodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' bcs-new-course ')]" . 223 "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' restore-course-search ')]" . 224 "/descendant::input[@type='radio']"; 225 $this->execute("behat_general::i_click_on", array($radionodexpath, 'xpath_element')); 226 227 // Pressing the continue button of the restore into an existing course section. 228 $continuenodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' bcs-new-course ')]" . 229 "/descendant::input[@type='submit'][@value='" . get_string('continue') . "']"; 230 $this->execute("behat_general::i_click_on", array($continuenodexpath, 'xpath_element')); 231 232 // Common restore process using provided key/value options. 233 $this->process_restore($options); 234 } 235 236 /** 237 * Merges the backup into the current course using the provided restore options. 238 * 239 * You should be in the 'Restore' page where the backup is. 240 * 241 * @Given /^I merge "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into the current course using this options:$/ 242 * @param string $backupfilename 243 * @param TableNode $options Restore forms options or false if no options provided 244 */ 245 public function i_merge_backup_into_the_current_course($backupfilename, $options = false) { 246 247 // Confirm restore. 248 $this->select_backup($backupfilename); 249 250 // Merge without deleting radio option. 251 $radionodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), 'bcs-current-course')]" . 252 "/descendant::input[@type='radio'][@name='target'][@value='1']"; 253 $this->execute("behat_general::i_click_on", array($radionodexpath, 'xpath_element')); 254 255 // Pressing the continue button of the restore merging section. 256 $continuenodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), 'bcs-current-course')]" . 257 "/descendant::input[@type='submit'][@value='" . get_string('continue') . "']"; 258 $this->execute("behat_general::i_click_on", array($continuenodexpath, 'xpath_element')); 259 260 // Common restore process using provided key/value options. 261 $this->process_restore($options); 262 } 263 264 /** 265 * Merges the backup into the current course after deleting this contents, using the provided restore options. 266 * 267 * You should be in the 'Restore' page where the backup is. 268 * 269 * @Given /^I merge "(?P<backup_filename_string>(?:[^"]|\\")*)" backup into the current course after deleting it's contents using this options:$/ 270 * @param string $backupfilename 271 * @param TableNode $options Restore forms options or false if no options provided 272 */ 273 public function i_merge_backup_into_current_course_deleting_its_contents($backupfilename, $options = false) { 274 275 // Confirm restore. 276 $this->select_backup($backupfilename); 277 278 // Delete contents radio option. 279 $radionodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), 'bcs-current-course')]" . 280 "/descendant::input[@type='radio'][@name='target'][@value='0']"; 281 $this->execute("behat_general::i_click_on", array($radionodexpath, 'xpath_element')); 282 283 // Pressing the continue button of the restore merging section. 284 $continuenodexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), 'bcs-current-course')]" . 285 "/descendant::input[@type='submit'][@value='" . get_string('continue') . "']"; 286 $this->execute("behat_general::i_click_on", array($continuenodexpath, 'xpath_element')); 287 288 // Common restore process using provided key/value options. 289 $this->process_restore($options); 290 } 291 292 /** 293 * Selects the backup to restore. 294 * 295 * @throws ExpectationException 296 * @param string $backupfilename 297 * @return void 298 */ 299 protected function select_backup($backupfilename) { 300 301 // Using xpath as there are other restore links before this one. 302 $exception = new ExpectationException('The "' . $backupfilename . '" backup file can not be found in this page', 303 $this->getSession()); 304 305 // The argument should be converted to an xpath literal. 306 $backupfilename = behat_context_helper::escape($backupfilename); 307 308 $xpath = "//tr[contains(., $backupfilename)]/descendant::a[contains(., '" . get_string('restore') . "')]"; 309 $restorelink = $this->find('xpath', $xpath, $exception); 310 $restorelink->click(); 311 312 // Confirm the backup contents. 313 $this->find_button(get_string('continue'))->press(); 314 } 315 316 /** 317 * Executes the common steps of all restore processes. 318 * 319 * @param TableNode $options The backup and restore options or false if no options provided 320 * @return void 321 */ 322 protected function process_restore($options) { 323 324 // We can not use other steps here as we don't know where the provided data 325 // table elements are used, and we need to catch exceptions contantly. 326 327 // Settings. 328 $this->fill_backup_restore_form($this->get_step_options($options, "Settings")); 329 $this->execute("behat_forms::press_button", get_string('restorestage4action', 'backup')); 330 331 // Schema. 332 $this->fill_backup_restore_form($this->get_step_options($options, "Schema")); 333 $this->execute("behat_forms::press_button", get_string('restorestage8action', 'backup')); 334 335 // Review, no options here. 336 $this->execute("behat_forms::press_button", get_string('restorestage16action', 'backup')); 337 338 // Wait till the final button is visible. 339 $this->execute("behat_general::wait_until_the_page_is_ready"); 340 341 // Last restore continue button, redirected to restore course after this. 342 $this->execute("behat_general::i_click_on", array(get_string('restorestage32action', 'backup'), 'button')); 343 } 344 345 /** 346 * Tries to fill the current page form elements with the provided options. 347 * 348 * This step is slow as it spins over each provided option, we are 349 * not expected to have lots of provided options, anyways, is better 350 * to be conservative and wait for the elements to appear rather than 351 * to have false failures. 352 * 353 * @param TableNode $options The backup and restore options or false if no options provided 354 * @return void 355 */ 356 protected function fill_backup_restore_form($options) { 357 358 // Nothing to fill if no options are provided. 359 if (!$options) { 360 return; 361 } 362 363 // If we find any of the provided options in the current form we should set the value. 364 $datahash = $options->getRowsHash(); 365 foreach ($datahash as $locator => $value) { 366 $field = behat_field_manager::get_form_field_from_label($locator, $this); 367 $field->set_value($value); 368 } 369 } 370 371 /** 372 * Get the options specific to this step of the backup/restore process. 373 * 374 * @param TableNode $options The options table to filter 375 * @param string $step The name of the step 376 * @return TableNode The filtered options table 377 * @throws ExpectationException 378 */ 379 protected function get_step_options($options, $step) { 380 // Nothing to fill if no options are provided. 381 if (!$options) { 382 return; 383 } 384 385 $rows = $options->getRows(); 386 $newrows = array(); 387 foreach ($rows as $k => $data) { 388 if (count($data) !== 3) { 389 // Not enough information to guess the page. 390 throw new ExpectationException("The backup/restore step must be specified for all backup options", 391 $this->getSession()); 392 } else if ($data[0] == $step) { 393 unset($data[0]); 394 $newrows[] = $data; 395 } 396 } 397 $pageoptions = new TableNode($newrows); 398 399 return $pageoptions; 400 } 401 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body