Esempio n. 1
0
 /**
  * Internal step definition to find exceptions, debugging() messages and PHP debug messages.
  *
  * Part of behat_hooks class as is part of the testing framework, is auto-executed
  * after each step so no features will splicitly use it.
  *
  * @throws Exception Unknown type, depending on what we caught in the hook or basic \Exception.
  * @see Moodle\BehatExtension\Tester\MoodleStepTester
  */
 public function look_for_exceptions()
 {
     // Wrap in try in case we were interacting with a closed window.
     try {
         // Exceptions.
         $exceptionsxpath = "//div[@data-rel='fatalerror']";
         // Debugging messages.
         $debuggingxpath = "//div[@data-rel='debugging']";
         // PHP debug messages.
         $phperrorxpath = "//div[@data-rel='phpdebugmessage']";
         // Any other backtrace.
         $othersxpath = "(//*[contains(., ': call to ')])[1]";
         $xpaths = array($exceptionsxpath, $debuggingxpath, $phperrorxpath, $othersxpath);
         $joinedxpath = implode(' | ', $xpaths);
         // Joined xpath expression. Most of the time there will be no exceptions, so this pre-check
         // is faster than to send the 4 xpath queries for each step.
         if (!$this->getSession()->getDriver()->find($joinedxpath)) {
             // Check if we have recorded any errors in driver process.
             $phperrors = behat_get_shutdown_process_errors();
             if (!empty($phperrors)) {
                 foreach ($phperrors as $error) {
                     $errnostring = behat_get_error_string($error['type']);
                     $msgs[] = $errnostring . ": " . $error['message'] . " at " . $error['file'] . ": " . $error['line'];
                 }
                 $msg = "PHP errors found:\n" . implode("\n", $msgs);
                 throw new \Exception(htmlentities($msg));
             }
             return;
         }
         // Exceptions.
         if ($errormsg = $this->getSession()->getPage()->find('xpath', $exceptionsxpath)) {
             // Getting the debugging info and the backtrace.
             $errorinfoboxes = $this->getSession()->getPage()->findAll('css', 'div.alert-error');
             // If errorinfoboxes is empty, try find alert-danger (bootstrap4) class.
             if (empty($errorinfoboxes)) {
                 $errorinfoboxes = $this->getSession()->getPage()->findAll('css', 'div.alert-danger');
             }
             // If errorinfoboxes is empty, try find notifytiny (original) class.
             if (empty($errorinfoboxes)) {
                 $errorinfoboxes = $this->getSession()->getPage()->findAll('css', 'div.notifytiny');
             }
             // If errorinfoboxes is empty, try find ajax/JS exception in dialogue.
             if (empty($errorinfoboxes)) {
                 $errorinfoboxes = $this->getSession()->getPage()->findAll('css', 'div.moodle-exception-message');
                 // If ajax/JS exception.
                 if ($errorinfoboxes) {
                     $errorinfo = $this->get_debug_text($errorinfoboxes[0]->getHtml());
                 }
             } else {
                 $errorinfo = $this->get_debug_text($errorinfoboxes[0]->getHtml()) . "\n" . $this->get_debug_text($errorinfoboxes[1]->getHtml());
             }
             $msg = "Moodle exception: " . $errormsg->getText() . "\n" . $errorinfo;
             throw new \Exception(html_entity_decode($msg));
         }
         // Debugging messages.
         if ($debuggingmessages = $this->getSession()->getPage()->findAll('xpath', $debuggingxpath)) {
             $msgs = array();
             foreach ($debuggingmessages as $debuggingmessage) {
                 $msgs[] = $this->get_debug_text($debuggingmessage->getHtml());
             }
             $msg = "debugging() message/s found:\n" . implode("\n", $msgs);
             throw new \Exception(html_entity_decode($msg));
         }
         // PHP debug messages.
         if ($phpmessages = $this->getSession()->getPage()->findAll('xpath', $phperrorxpath)) {
             $msgs = array();
             foreach ($phpmessages as $phpmessage) {
                 $msgs[] = $this->get_debug_text($phpmessage->getHtml());
             }
             $msg = "PHP debug message/s found:\n" . implode("\n", $msgs);
             throw new \Exception(html_entity_decode($msg));
         }
         // Any other backtrace.
         // First looking through xpath as it is faster than get and parse the whole page contents,
         // we get the contents and look for matches once we found something to suspect that there is a backtrace.
         if ($this->getSession()->getDriver()->find($othersxpath)) {
             $backtracespattern = '/(line [0-9]* of [^:]*: call to [\\->&;:a-zA-Z_\\x7f-\\xff][\\->&;:a-zA-Z0-9_\\x7f-\\xff]*)/';
             if (preg_match_all($backtracespattern, $this->getSession()->getPage()->getContent(), $backtraces)) {
                 $msgs = array();
                 foreach ($backtraces[0] as $backtrace) {
                     $msgs[] = $backtrace . '()';
                 }
                 $msg = "Other backtraces found:\n" . implode("\n", $msgs);
                 throw new \Exception(htmlentities($msg));
             }
         }
     } catch (NoSuchWindow $e) {
         // If we were interacting with a popup window it will not exists after closing it.
     }
 }
Esempio n. 2
0
/**
 * Before shutdown save last error entries, so we can fail the test.
 */
function behat_shutdown_function() {
    // If any error found, then save it.
    if ($error = error_get_last()) {
        // Ignore E_WARNING, as they might come via ( @ )suppression and might lead to false failure.
        if (isset($error['type']) && !($error['type'] & E_WARNING)) {

            $errors = behat_get_shutdown_process_errors();

            $errors[] = $error;
            $errorstosave = json_encode($errors);

            set_config('process_errors', $errorstosave, 'tool_behat');
        }
    }
}