From 2735b7ff8d3dbf862dc37767bcaf3695b5037ce8 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Mon, 12 Nov 2018 12:11:06 +0000 Subject: [PATCH 001/220] MDL-63977 Behat: Allow Behat testing of the Moodle mobile app This change allows you to write and run Behat tests that cover the mobile app. These should have the @app tag. They will be run in the Chrome browser using an Ionic server on the local machine. See config-dist.php for configuration settings, or full docs here: https://docs.moodle.org/dev/Acceptance_testing_for_the_mobile_app --- app_behat_runtime.js | 635 +++++++++++++++++++++++++++++++++++++++++++ behat_app.php | 524 +++++++++++++++++++++++++++++++++++ 2 files changed, 1159 insertions(+) create mode 100644 app_behat_runtime.js create mode 100644 behat_app.php diff --git a/app_behat_runtime.js b/app_behat_runtime.js new file mode 100644 index 000000000..ca396a22e --- /dev/null +++ b/app_behat_runtime.js @@ -0,0 +1,635 @@ +(function() { + // Set up the M object - only pending_js is implemented. + window.M = window.M ? window.M : {}; + var M = window.M; + M.util = M.util ? M.util : {}; + M.util.pending_js = M.util.pending_js ? M.util.pending_js : []; // eslint-disable-line camelcase + + /** + * Logs information from this Behat runtime JavaScript, including the time and the 'BEHAT' + * keyword so we can easily filter for it if needed. + * + * @param {string} text Information to log + */ + var log = function(text) { + var now = new Date(); + var nowFormatted = String(now.getHours()).padStart(2, '0') + ':' + + String(now.getMinutes()).padStart(2, '0') + ':' + + String(now.getSeconds()).padStart(2, '0') + '.' + + String(now.getMilliseconds()).padStart(2, '0'); + console.log('BEHAT: ' + nowFormatted + ' ' + text); // eslint-disable-line no-console + }; + + /** + * Run after several setTimeouts to ensure queued events are finished. + * + * @param {function} target function to run + * @param {number} count Number of times to do setTimeout (leave blank for 10) + */ + var runAfterEverything = function(target, count) { + if (count === undefined) { + count = 10; + } + setTimeout(function() { + count--; + if (count == 0) { + target(); + } else { + runAfterEverything(target, count); + } + }, 0); + }; + + /** + * Adds a pending key to the array. + * + * @param {string} key Key to add + */ + var addPending = function(key) { + // Add a special DELAY entry whenever another entry is added. + if (window.M.util.pending_js.length == 0) { + window.M.util.pending_js.push('DELAY'); + } + window.M.util.pending_js.push(key); + + log('PENDING+: ' + window.M.util.pending_js); + }; + + /** + * Removes a pending key from the array. If this would clear the array, the actual clear only + * takes effect after the queued events are finished. + * + * @param {string} key Key to remove + */ + var removePending = function(key) { + // Remove the key immediately. + window.M.util.pending_js = window.M.util.pending_js.filter(function(x) { // eslint-disable-line camelcase + return x !== key; + }); + log('PENDING-: ' + window.M.util.pending_js); + + // If the only thing left is DELAY, then remove that as well, later... + if (window.M.util.pending_js.length === 1) { + runAfterEverything(function() { + // Check there isn't a spinner... + updateSpinner(); + + // Only remove it if the pending array is STILL empty after all that. + if (window.M.util.pending_js.length === 1) { + window.M.util.pending_js = []; // eslint-disable-line camelcase + log('PENDING-: ' + window.M.util.pending_js); + } + }); + } + }; + + /** + * Adds a pending key to the array, but removes it after some setTimeouts finish. + */ + var addPendingDelay = function() { + addPending('...'); + removePending('...'); + }; + + // Override XMLHttpRequest to mark things pending while there is a request waiting. + var realOpen = XMLHttpRequest.prototype.open; + var requestIndex = 0; + XMLHttpRequest.prototype.open = function() { + var index = requestIndex++; + var key = 'httprequest-' + index; + + // Add to the list of pending requests. + addPending(key); + + // Detect when it finishes and remove it from the list. + this.addEventListener('loadend', function() { + removePending(key); + }); + + return realOpen.apply(this, arguments); + }; + + var waitingSpinner = false; + + /** + * Checks if a loading spinner is present and visible; if so, adds it to the pending array + * (and if not, removes it). + */ + var updateSpinner = function() { + var spinner = document.querySelector('span.core-loading-spinner'); + if (spinner && spinner.offsetParent) { + if (!waitingSpinner) { + addPending('spinner'); + waitingSpinner = true; + } + } else { + if (waitingSpinner) { + removePending('spinner'); + waitingSpinner = false; + } + } + }; + + // It would be really beautiful if you could detect CSS transitions and animations, that would + // cover almost everything, but sadly there is no way to do this because the transitionstart + // and animationcancel events are not implemented in Chrome, so we cannot detect either of + // these reliably. Instead, we have to look for any DOM changes and do horrible polling. Most + // of the animations are set to 500ms so we allow it to continue from 500ms after any DOM + // change. + + var recentMutation = false; + var lastMutation; + + /** + * Called from the mutation callback to remove the pending tag after 500ms if nothing else + * gets mutated. + * + * This will be called after 500ms, then every 100ms until there have been no mutation events + * for 500ms. + */ + var pollRecentMutation = function() { + if (Date.now() - lastMutation > 500) { + recentMutation = false; + removePending('dom-mutation'); + } else { + setTimeout(pollRecentMutation, 100); + } + }; + + /** + * Mutation callback, called whenever the DOM is mutated. + */ + var mutationCallback = function() { + lastMutation = Date.now(); + if (!recentMutation) { + recentMutation = true; + addPending('dom-mutation'); + setTimeout(pollRecentMutation, 500); + } + // Also update the spinner presence if needed. + updateSpinner(); + }; + + // Set listener using the mutation callback. + var observer = new MutationObserver(mutationCallback); + observer.observe(document, {attributes: true, childList: true, subtree: true}); + + /** + * Generic shared function to find possible xpath matches within the document, that are visible, + * and then process them using a callback function. + * + * @param {string} xpath Xpath to use + * @param {function} process Callback function that handles each matched node + */ + var findPossibleMatches = function(xpath, process) { + var matches = document.evaluate(xpath, document); + while (true) { + var match = matches.iterateNext(); + if (!match) { + break; + } + // Skip invisible text nodes. + if (!match.offsetParent) { + continue; + } + + process(match); + } + }; + + /** + * Function to find an element based on its text or Aria label. + * + * @param {string} text Text (full or partial) + * @param {string} [near] Optional 'near' text - if specified, must have a single match on page + * @return {HTMLElement} Found element + * @throws {string} Error message beginning 'ERROR:' if something went wrong + */ + var findElementBasedOnText = function(text, near) { + // Find all the elements that contain this text (and don't have a child element that + // contains it - i.e. the most specific elements). + var escapedText = text.replace('"', '""'); + var exactMatches = []; + var anyMatches = []; + findPossibleMatches('//*[contains(normalize-space(.), "' + escapedText + + '") and not(child::*[contains(normalize-space(.), "' + escapedText + '")])]', + function(match) { + // Get the text. Note that innerText returns capitalised values for Android buttons + // for some reason, so we'll have to do a case-insensitive match. + var matchText = match.innerText.trim().toLowerCase(); + + // Let's just check - is this actually a label for something else? If so we will click + // that other thing instead. + var labelId = document.evaluate('string(ancestor-or-self::ion-label[@id][1]/@id)', match).stringValue; + if (labelId) { + var target = document.querySelector('*[aria-labelledby=' + labelId + ']'); + if (target) { + match = target; + } + } + + // Add to array depending on if it's an exact or partial match. + if (matchText === text.toLowerCase()) { + exactMatches.push(match); + } else { + anyMatches.push(match); + } + }); + + // Find all the Aria labels that contain this text. + var exactLabelMatches = []; + var anyLabelMatches = []; + findPossibleMatches('//*[@aria-label and contains(@aria-label, "' + escapedText + + '")]', function(match) { + // Add to array depending on if it's an exact or partial match. + if (match.getAttribute('aria-label').trim() === text) { + exactLabelMatches.push(match); + } else { + anyLabelMatches.push(match); + } + }); + + // If the 'near' text is set, use it to filter results. + var nearAncestors = []; + if (near !== undefined) { + escapedText = near.replace('"', '""'); + var exactNearMatches = []; + var anyNearMatches = []; + findPossibleMatches('//*[contains(normalize-space(.), "' + escapedText + + '") and not(child::*[contains(normalize-space(.), "' + escapedText + + '")])]', function(match) { + // Get the text. + var matchText = match.innerText.trim(); + + // Add to array depending on if it's an exact or partial match. + if (matchText === text) { + exactNearMatches.push(match); + } else { + anyNearMatches.push(match); + } + }); + + var nearFound = null; + + // If there is an exact text match, use that (regardless of other matches). + if (exactNearMatches.length > 1) { + throw new Error('Too many exact matches for near text'); + } else if (exactNearMatches.length) { + nearFound = exactNearMatches[0]; + } + + if (nearFound === null) { + // If there is one partial text match, use that. + if (anyNearMatches.length > 1) { + throw new Error('Too many partial matches for near text'); + } else if (anyNearMatches.length) { + nearFound = anyNearMatches[0]; + } + } + + if (!nearFound) { + throw new Error('No matches for near text'); + } + + while (nearFound) { + nearAncestors.push(nearFound); + nearFound = nearFound.parentNode; + } + + /** + * Checks the number of steps up the tree from a specified node before getting to an + * ancestor of the 'near' item + * + * @param {HTMLElement} node HTML node + * @returns {number} Number of steps up, or Number.MAX_SAFE_INTEGER if it never matched + */ + var calculateNearDepth = function(node) { + var depth = 0; + while (node) { + if (nearAncestors.indexOf(node) !== -1) { + return depth; + } + node = node.parentNode; + depth++; + } + return Number.MAX_SAFE_INTEGER; + }; + + /** + * Reduces an array to include only the nearest in each category. + * + * @param {Array} arr Array to + * @return {Array} Array including only the items with minimum 'near' depth + */ + var filterNonNearest = function(arr) { + var nearDepth = arr.map(function(node) { + return calculateNearDepth(node); + }); + var minDepth = Math.min.apply(null, nearDepth); + return arr.filter(function(element, index) { + return nearDepth[index] == minDepth; + }); + }; + + // Filter all the category arrays. + exactMatches = filterNonNearest(exactMatches); + exactLabelMatches = filterNonNearest(exactLabelMatches); + anyMatches = filterNonNearest(anyMatches); + anyLabelMatches = filterNonNearest(anyLabelMatches); + } + + // Select the resulting match. Note this 'do' loop is not really a loop, it is just so we + // can easily break out of it as soon as we find a match. + var found = null; + do { + // If there is an exact text match, use that (regardless of other matches). + if (exactMatches.length > 1) { + throw new Error('Too many exact matches for text'); + } else if (exactMatches.length) { + found = exactMatches[0]; + break; + } + + // If there is an exact label match, use that. + if (exactLabelMatches.length > 1) { + throw new Error('Too many exact label matches for text'); + } else if (exactLabelMatches.length) { + found = exactLabelMatches[0]; + break; + } + + // If there is one partial text match, use that. + if (anyMatches.length > 1) { + throw new Error('Too many partial matches for text'); + } else if (anyMatches.length) { + found = anyMatches[0]; + break; + } + + // Finally if there is one partial label match, use that. + if (anyLabelMatches.length > 1) { + throw new Error('Too many partial label matches for text'); + } else if (anyLabelMatches.length) { + found = anyLabelMatches[0]; + break; + } + } while (false); + + if (!found) { + throw new Error('No matches for text'); + } + + return found; + }; + + /** + * Function to find and click an app standard button. + * + * @param {string} button Type of button to press + * @return {string} OK if successful, or ERROR: followed by message + */ + window.behatPressStandard = function(button) { + log('Action - Click standard button: ' + button); + var selector; + switch (button) { + case 'back' : + selector = 'ion-navbar > button.back-button-md'; + break; + case 'main menu' : + selector = 'page-core-mainmenu .tab-button > ion-icon[aria-label=more]'; + break; + case 'page menu' : + selector = 'core-context-menu > button[aria-label=Info]'; + break; + default: + return 'ERROR: Unsupported standard button type'; + } + var buttons = Array.from(document.querySelectorAll(selector)); + var foundButton = null; + var tooMany = false; + buttons.forEach(function(button) { + if (button.offsetParent) { + if (foundButton === null) { + foundButton = button; + } else { + tooMany = true; + } + } + }); + if (!foundButton) { + return 'ERROR: Could not find button'; + } + if (tooMany) { + return 'ERROR: Found too many buttons'; + } + foundButton.click(); + + // Mark busy until the button click finishes processing. + addPendingDelay(); + + return 'OK'; + }; + + /** + * When there is a popup, clicks on the backdrop. + * + * @return {string} OK if successful, or ERROR: followed by message + */ + window.behatClosePopup = function() { + log('Action - Close popup'); + + var backdrops = Array.from(document.querySelectorAll('ion-backdrop')); + var found = null; + var tooMany = false; + backdrops.forEach(function(backdrop) { + if (backdrop.offsetParent) { + if (found === null) { + found = backdrop; + } else { + tooMany = true; + } + } + }); + if (!found) { + return 'ERROR: Could not find backdrop'; + } + if (tooMany) { + return 'ERROR: Found too many backdrops'; + } + found.click(); + + // Mark busy until the click finishes processing. + addPendingDelay(); + + return 'OK'; + }; + + /** + * Function to press arbitrary item based on its text or Aria label. + * + * @param {string} text Text (full or partial) + * @param {string} near Optional 'near' text - if specified, must have a single match on page + * @return {string} OK if successful, or ERROR: followed by message + */ + window.behatPress = function(text, near) { + log('Action - Press ' + text + (near === undefined ? '' : ' - near ' + near)); + + var found; + try { + found = findElementBasedOnText(text, near); + } catch (error) { + return 'ERROR: ' + error.message; + } + + // Simulate a mouse click on the button. + found.scrollIntoView(); + var rect = found.getBoundingClientRect(); + var eventOptions = {clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2, + bubbles: true, view: window, cancelable: true}; + setTimeout(function() { + found.dispatchEvent(new MouseEvent('mousedown', eventOptions)); + }, 0); + setTimeout(function() { + found.dispatchEvent(new MouseEvent('mouseup', eventOptions)); + }, 0); + setTimeout(function() { + found.dispatchEvent(new MouseEvent('click', eventOptions)); + }, 0); + + // Mark busy until the button click finishes processing. + addPendingDelay(); + + return 'OK'; + }; + + /** + * Gets the currently displayed page header. + * + * @return {string} OK: followed by header text if successful, or ERROR: followed by message. + */ + window.behatGetHeader = function() { + log('Action - Get header'); + + var result = null; + var resultCount = 0; + var titles = Array.from(document.querySelectorAll('ion-header ion-title')); + titles.forEach(function(title) { + if (title.offsetParent) { + result = title.innerText.trim(); + resultCount++; + } + }); + + if (resultCount > 1) { + return 'ERROR: Too many possible titles'; + } else if (!resultCount) { + return 'ERROR: No title found'; + } else { + return 'OK:' + result; + } + }; + + /** + * Sets the text of a field to the specified value. + * + * This currently matches fields only based on the placeholder attribute. + * + * @param {string} field Field name + * @param {string} value New value + * @return {string} OK or ERROR: followed by message + */ + window.behatSetField = function(field, value) { + log('Action - Set field ' + field + ' to: ' + value); + + // Find input(s) with given placeholder. + var escapedText = field.replace('"', '""'); + var exactMatches = []; + var anyMatches = []; + findPossibleMatches( + '//input[contains(@placeholder, "' + escapedText + '")] |' + + '//textarea[contains(@placeholder, "' + escapedText + '")] |' + + '//core-rich-text-editor/descendant::div[contains(@data-placeholder-text, "' + + escapedText + '")]', function(match) { + // Add to array depending on if it's an exact or partial match. + var placeholder; + if (match.nodeName === 'DIV') { + placeholder = match.getAttribute('data-placeholder-text'); + } else { + placeholder = match.getAttribute('placeholder'); + } + if (placeholder.trim() === field) { + exactMatches.push(match); + } else { + anyMatches.push(match); + } + }); + + // Select the resulting match. + var found = null; + do { + // If there is an exact text match, use that (regardless of other matches). + if (exactMatches.length > 1) { + return 'ERROR: Too many exact placeholder matches for text'; + } else if (exactMatches.length) { + found = exactMatches[0]; + break; + } + + // If there is one partial text match, use that. + if (anyMatches.length > 1) { + return 'ERROR: Too many partial placeholder matches for text'; + } else if (anyMatches.length) { + found = anyMatches[0]; + break; + } + } while (false); + + if (!found) { + return 'ERROR: No matches for text'; + } + + // Functions to get/set value depending on field type. + var setValue; + var getValue; + switch (found.nodeName) { + case 'INPUT': + case 'TEXTAREA': + setValue = function(text) { + found.value = text; + }; + getValue = function() { + return found.value; + }; + break; + case 'DIV': + setValue = function(text) { + found.innerHTML = text; + }; + getValue = function() { + return found.innerHTML; + }; + break; + } + + // Pretend we have cut and pasted the new text. + var event; + if (getValue() !== '') { + event = new InputEvent('input', {bubbles: true, view: window, cancelable: true, + inputType: 'devareByCut'}); + setTimeout(function() { + setValue(''); + found.dispatchEvent(event); + }, 0); + } + if (value !== '') { + event = new InputEvent('input', {bubbles: true, view: window, cancelable: true, + inputType: 'insertFromPaste', data: value}); + setTimeout(function() { + setValue(value); + found.dispatchEvent(event); + }, 0); + } + + return 'OK'; + }; +})(); diff --git a/behat_app.php b/behat_app.php new file mode 100644 index 000000000..f5d723dd2 --- /dev/null +++ b/behat_app.php @@ -0,0 +1,524 @@ +. + +/** + * Mobile/desktop app steps definitions. + * + * @package core + * @category test + * @copyright 2018 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../behat/behat_base.php'); + +use Behat\Mink\Exception\DriverException; +use Behat\Mink\Exception\ExpectationException; +use Behat\Behat\Hook\Scope\BeforeScenarioScope; + +/** + * Mobile/desktop app steps definitions. + * + * @package core + * @category test + * @copyright 2018 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_app extends behat_base { + /** @var bool True if the current scenario has the app tag */ + protected $apptag = false; + + /** @var stdClass Object with data about launched Ionic instance (if any) */ + protected static $ionicrunning = null; + + /** + * Checks if the current OS is Windows, from the point of view of task-executing-and-killing. + * + * @return bool True if Windows + */ + protected static function is_windows() : bool { + return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; + } + + /** + * Checks tags before each scenario. + * + * @BeforeScenario + * @param BeforeScenarioScope $scope Scope information + */ + public function check_tags(BeforeScenarioScope $scope) { + $this->apptag = in_array('app', $scope->getScenario()->getTags()) || + in_array('app', $scope->getFeature()->getTags()); + } + + /** + * Opens the Moodle app in the browser. + * + * Requires JavaScript. + * + * @Given /^I enter the app$/ + * @throws DriverException Issue with configuration or feature file + * @throws dml_exception Problem with Moodle setup + * @throws ExpectationException Problem with resizing window + */ + public function i_enter_the_app() { + // Restart the browser and set its size. + $this->getSession()->restart(); + $this->resize_window('360x720', true); + + // Prepare setup. + $this->check_behat_setup(); + $this->fix_moodle_setup(); + + // Start Ionic server (or use existing one). + $url = $this->start_or_reuse_ionic(); + + // Go to page and prepare browser for app. + $this->prepare_browser($url); + } + + /** + * Checks the Behat setup - tags and configuration. + * + * @throws DriverException + */ + protected function check_behat_setup() { + global $CFG; + + // Check the app tag was set. + if (!$this->apptag) { + throw new DriverException('Requires @app tag on scenario or feature.'); + } + + // Check JavaScript is enabled. + if (!$this->running_javascript()) { + throw new DriverException('The app requires JavaScript.'); + } + + // Check the config settings are defined. + if (empty($CFG->behat_ionicaddress) && empty($CFG->behat_approot)) { + throw new DriverException('$CFG->behat_ionicaddress or $CFG->behat_approot must be defined.'); + } + } + + /** + * Fixes the Moodle admin settings to allow mobile app use (if not already correct). + * + * @throws dml_exception If there is any problem changing Moodle settings + */ + protected function fix_moodle_setup() { + global $CFG, $DB; + + // Configure Moodle settings to enable app web services. + if (!$CFG->enablewebservices) { + set_config('enablewebservices', 1); + } + if (!$CFG->enablemobilewebservice) { + set_config('enablemobilewebservice', 1); + } + + // Add 'Create token' and 'Use REST webservice' permissions to authenticated user role. + $userroleid = $DB->get_field('role', 'id', ['shortname' => 'user']); + $systemcontext = \context_system::instance(); + role_change_permission($userroleid, $systemcontext, 'moodle/webservice:createtoken', CAP_ALLOW); + role_change_permission($userroleid, $systemcontext, 'webservice/rest:use', CAP_ALLOW); + + // Check the value of the 'webserviceprotocols' config option. Due to weird behaviour + // in Behat with regard to config variables that aren't defined in a settings.php, the + // value in $CFG here may reflect a previous run, so get it direct from the database + // instead. + $field = $DB->get_field('config', 'value', ['name' => 'webserviceprotocols'], IGNORE_MISSING); + if (empty($field)) { + $protocols = []; + } else { + $protocols = explode(',', $field); + } + if (!in_array('rest', $protocols)) { + $protocols[] = 'rest'; + set_config('webserviceprotocols', implode(',', $protocols)); + } + + // Enable mobile service. + require_once($CFG->dirroot . '/webservice/lib.php'); + $webservicemanager = new webservice(); + $service = $webservicemanager->get_external_service_by_shortname( + MOODLE_OFFICIAL_MOBILE_SERVICE, MUST_EXIST); + if (!$service->enabled) { + $service->enabled = 1; + $webservicemanager->update_external_service($service); + } + + // If installed, also configure local_mobile plugin to enable additional features service. + $localplugins = core_component::get_plugin_list('local'); + if (array_key_exists('mobile', $localplugins)) { + $service = $webservicemanager->get_external_service_by_shortname( + 'local_mobile', MUST_EXIST); + if (!$service->enabled) { + $service->enabled = 1; + $webservicemanager->update_external_service($service); + } + } + } + + /** + * Starts an Ionic server if necessary, or uses an existing one. + * + * @return string URL to Ionic server + * @throws DriverException If there's a system error starting Ionic + */ + protected function start_or_reuse_ionic() { + global $CFG; + + if (!empty($CFG->behat_ionicaddress)) { + // Use supplied Ionic server which should already be running. + $url = $CFG->behat_ionicaddress; + } else if (self::$ionicrunning) { + // Use existing Ionic instance launched previously. + $url = self::$ionicrunning->url; + } else { + // Open Ionic process in relevant path. + $path = realpath($CFG->behat_approot); + $stderrfile = $CFG->dataroot . '/behat/ionic-stderr.log'; + $prefix = ''; + // Except on Windows, use 'exec' so that we get the pid of the actual Node process + // and not the shell it uses to execute. You can't do exec on Windows; there is a + // bypass_shell option but it is not the same thing and isn't usable here. + if (!self::is_windows()) { + $prefix = 'exec '; + } + $process = proc_open($prefix . 'ionic serve --no-interactive --no-open', + [['pipe', 'r'], ['pipe', 'w'], ['file', $stderrfile, 'w']], $pipes, $path); + if ($process === false) { + throw new DriverException('Error starting Ionic process'); + } + fclose($pipes[0]); + + // Get pid - we will need this to kill the process. + $status = proc_get_status($process); + $pid = $status['pid']; + + // Read data from stdout until the server comes online. + // Note: On Windows it is impossible to read simultaneously from stderr and stdout + // because stream_select and non-blocking I/O don't work on process pipes, so that is + // why stderr was redirected to a file instead. Also, this code is simpler. + $url = null; + $stdoutlog = ''; + while (true) { + $line = fgets($pipes[1], 4096); + if ($line === false) { + break; + } + + $stdoutlog .= $line; + + if (preg_match('~^\s*Local: (http\S*)~', $line, $matches)) { + $url = $matches[1]; + break; + } + } + + // If it failed, close the pipes and the process. + if (!$url) { + fclose($pipes[1]); + proc_close($process); + $logpath = $CFG->dataroot . '/behat/ionic-start.log'; + $stderrlog = file_get_contents($stderrfile); + @unlink($stderrfile); + file_put_contents($logpath, + "Ionic startup log from " . date('c') . + "\n\n----STDOUT----\n$stdoutlog\n\n----STDERR----\n$stderrlog"); + throw new DriverException('Unable to start Ionic. See ' . $logpath); + } + + // Remember the URL, so we can reuse it next time, and other details so we can kill + // the process. + self::$ionicrunning = (object)['url' => $url, 'process' => $process, 'pipes' => $pipes, + 'pid' => $pid]; + } + return $url; + } + + /** + * Closes Ionic (if it was started) at end of test suite. + * + * @AfterSuite + */ + public static function close_ionic() { + if (self::$ionicrunning) { + fclose(self::$ionicrunning->pipes[1]); + + if (self::is_windows()) { + // Using proc_terminate here does not work. It terminates the process but not any + // other processes it might have launched. Instead, we need to use an OS-specific + // mechanism to kill the process and children based on its pid. + exec('taskkill /F /T /PID ' . self::$ionicrunning->pid); + } else { + // On Unix this actually works, although only due to the 'exec' command inserted + // above. + proc_terminate(self::$ionicrunning->process); + } + self::$ionicrunning = null; + } + } + + /** + * Goes to the app page and then sets up some initial JavaScript so we can use it. + * + * @param string $url App URL + * @throws DriverException If the app fails to load properly + */ + protected function prepare_browser(string $url) { + global $CFG; + + // Visit the Ionic URL and wait for it to load. + $this->getSession()->visit($url); + $this->spin( + function($context, $args) { + $title = $context->getSession()->getPage()->find('xpath', '//title'); + if ($title) { + $text = $title->getHtml(); + if ($text === 'Moodle Desktop') { + return true; + } + } + throw new DriverException('Moodle app not found in browser'); + }, false, 30); + + // Run the scripts to install Moodle 'pending' checks. + $this->getSession()->executeScript( + file_get_contents(__DIR__ . '/app_behat_runtime.js')); + + // Wait until the site login field appears OR the main page. + $situation = $this->spin( + function($context, $args) { + $input = $context->getSession()->getPage()->find('xpath', '//input[@name="url"]'); + if ($input) { + return 'login'; + } + $mainmenu = $context->getSession()->getPage()->find('xpath', '//page-core-mainmenu'); + if ($mainmenu) { + return 'mainpage'; + } + throw new DriverException('Moodle app login URL prompt not found'); + }, false, 30); + + // If it's the login page, we automatically fill in the URL and leave it on the user/pass + // page. If it's the main page, we just leave it there. + if ($situation === 'login') { + $this->i_set_the_field_in_the_app('Site address', $CFG->wwwroot); + $this->i_press_in_the_app('Connect!'); + } + + // Continue only after JS finishes. + $this->wait_for_pending_js(); + } + + /** + * Logs in as the given user in the app's login screen. + * + * Must be run from the app login screen (i.e. immediately after first 'I enter the app'). + * + * @Given /^I log in as "(?P(?:[^"]|\\")*)" in the app$/ + * @param string $username Username (and password) + * @throws DriverException If the main page doesn't load + */ + public function i_log_in_as_username_in_the_app(string $username) { + $this->i_set_the_field_in_the_app('Username', $username); + $this->i_set_the_field_in_the_app('Password', $username); + + // Note there are two 'Log in' texts visible (the title and the button) so we have to use + // the 'near' syntax here. + $this->i_press_near_in_the_app('Log in', 'Forgotten'); + + // Wait until the main page appears. + $this->spin( + function($context, $args) { + $mainmenu = $context->getSession()->getPage()->find('xpath', '//page-core-mainmenu'); + if ($mainmenu) { + return 'mainpage'; + } + throw new DriverException('Moodle app main page not loaded after login'); + }, false, 30); + + // Wait for JS to finish as well. + $this->wait_for_pending_js(); + } + + /** + * Presses standard buttons in the app. + * + * @Given /^I press the (?Pback|main menu|page menu) button in the app$/ + * @param string $button Button type + * @throws DriverException If the button push doesn't work + */ + public function i_press_the_standard_button_in_the_app(string $button) { + $this->spin(function($context, $args) use ($button) { + $result = $this->getSession()->evaluateScript('return window.behatPressStandard("' . + $button . '");'); + if ($result !== 'OK') { + throw new DriverException('Error pressing standard button - ' . $result); + } + return true; + }); + $this->wait_for_pending_js(); + } + + /** + * Closes a popup by clicking on the 'backdrop' behind it. + * + * @Given /^I close the popup in the app$/ + * @throws DriverException If there isn't a popup to close + */ + public function i_close_the_popup_in_the_app() { + $this->spin(function($context, $args) { + $result = $this->getSession()->evaluateScript('return window.behatClosePopup();'); + if ($result !== 'OK') { + throw new DriverException('Error closing popup - ' . $result); + } + return true; + }); + $this->wait_for_pending_js(); + } + + /** + * Clicks on / touches something that is visible in the app. + * + * Note it is difficult to use the standard 'click on' or 'press' steps because those do not + * distinguish visible items and the app always has many non-visible items in the DOM. + * + * @Given /^I press "(?P(?:[^"]|\\")*)" in the app$/ + * @param string $text Text identifying click target + * @throws DriverException If the press doesn't work + */ + public function i_press_in_the_app(string $text) { + $this->spin(function($context, $args) use ($text) { + $result = $this->getSession()->evaluateScript('return window.behatPress("' . + addslashes_js($text) . '");'); + if ($result !== 'OK') { + throw new DriverException('Error pressing item - ' . $result); + } + return true; + }); + $this->wait_for_pending_js(); + } + + /** + * Clicks on / touches something that is visible in the app, near some other text. + * + * This is the same as the other step, but when there are multiple matches, it picks the one + * nearest (in DOM terms) the second text. The second text should be an exact match, or a partial + * match that only has one result. + * + * @Given /^I press "(?P(?:[^"]|\\")*)" near "(?P(?:[^"]|\\")*)" in the app$/ + * @param string $text Text identifying click target + * @param string $near Text identifying a nearby unique piece of text + * @throws DriverException If the press doesn't work + */ + public function i_press_near_in_the_app(string $text, string $near) { + $this->spin(function($context, $args) use ($text, $near) { + $result = $this->getSession()->evaluateScript('return window.behatPress("' . + addslashes_js($text) . '", "' . addslashes_js($near) . '");'); + if ($result !== 'OK') { + throw new DriverException('Error pressing item - ' . $result); + } + return true; + }); + $this->wait_for_pending_js(); + } + + /** + * Sets a field to the given text value in the app. + * + * Currently this only works for input fields which must be identified using a partial or + * exact match on the placeholder text. + * + * @Given /^I set the field "(?P(?:[^"]|\\")*)" to "(?P(?:[^"]|\\")*)" in the app$/ + * @param string $field Text identifying field + * @param string $value Value for field + * @throws DriverException If the field set doesn't work + */ + public function i_set_the_field_in_the_app(string $field, string $value) { + $this->spin(function($context, $args) use ($field, $value) { + $result = $this->getSession()->evaluateScript('return window.behatSetField("' . + addslashes_js($field) . '", "' . addslashes_js($value) . '");'); + if ($result !== 'OK') { + throw new DriverException('Error setting field - ' . $result); + } + return true; + }); + $this->wait_for_pending_js(); + } + + /** + * Checks that the current header stripe in the app contains the expected text. + * + * This can be used to see if the app went to the expected page. + * + * @Then /^the header should be "(?P(?:[^"]|\\")*)" in the app$/ + * @param string $text Expected header text + * @throws DriverException If the header can't be retrieved + * @throws ExpectationException If the header text is different to the expected value + */ + public function the_header_should_be_in_the_app(string $text) { + $result = $this->spin(function($context, $args) { + $result = $this->getSession()->evaluateScript('return window.behatGetHeader();'); + if (substr($result, 0, 3) !== 'OK:') { + throw new DriverException('Error getting header - ' . $result); + } + return $result; + }); + $header = substr($result, 3); + if (trim($header) !== trim($text)) { + throw new ExpectationException('The header text was not as expected: \'' . $header . '\'', + $this->getSession()->getDriver()); + } + } + + /** + * Switches to a newly-opened browser tab. + * + * This assumes the app opened a new tab. + * + * @Given /^I switch to the browser tab opened by the app$/ + * @throws DriverException If there aren't exactly 2 tabs open + */ + public function i_switch_to_the_browser_tab_opened_by_the_app() { + $names = $this->getSession()->getWindowNames(); + if (count($names) !== 2) { + throw new DriverException('Expected to see 2 tabs open, not ' . count($names)); + } + $this->getSession()->switchToWindow($names[1]); + } + + /** + * Closes the current browser tab. + * + * This assumes it was opened by the app and you will now get back to the app. + * + * @Given /^I close the browser tab opened by the app$/ + * @throws DriverException If there aren't exactly 2 tabs open + */ + public function i_close_the_browser_tab_opened_by_the_app() { + $names = $this->getSession()->getWindowNames(); + if (count($names) !== 2) { + throw new DriverException('Expected to see 2 tabs open, not ' . count($names)); + } + $this->getSession()->getDriver()->executeScript('window.close()'); + $this->getSession()->switchToWindow($names[0]); + } +} From 5958b9dc1b496c61b5ca744c0e4e94a7e4139b22 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Tue, 15 Jan 2019 14:31:25 +0000 Subject: [PATCH 002/220] MDL-63977 Behat: Upgrade mobile tests to work with 3.6 app version --- app_behat_runtime.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app_behat_runtime.js b/app_behat_runtime.js index ca396a22e..354786e75 100644 --- a/app_behat_runtime.js +++ b/app_behat_runtime.js @@ -399,7 +399,9 @@ selector = 'page-core-mainmenu .tab-button > ion-icon[aria-label=more]'; break; case 'page menu' : - selector = 'core-context-menu > button[aria-label=Info]'; + // This lang string was changed in app version 3.6. + selector = 'core-context-menu > button[aria-label=Info], ' + + 'core-context-menu > button[aria-label=Information]'; break; default: return 'ERROR: Unsupported standard button type'; From ae110772cf43b6c2ca38cbee694392f761080465 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Tue, 15 Jan 2019 14:31:44 +0000 Subject: [PATCH 003/220] MDL-63977 Behat: Fix bug in 'near' calculation --- app_behat_runtime.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app_behat_runtime.js b/app_behat_runtime.js index 354786e75..b07b53e63 100644 --- a/app_behat_runtime.js +++ b/app_behat_runtime.js @@ -306,8 +306,9 @@ var calculateNearDepth = function(node) { var depth = 0; while (node) { - if (nearAncestors.indexOf(node) !== -1) { - return depth; + var ancestorDepth = nearAncestors.indexOf(node); + if (ancestorDepth !== -1) { + return depth + ancestorDepth; } node = node.parentNode; depth++; From e6299d9a5fa034761e880a041d98fa26fd365830 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Tue, 15 Jan 2019 14:54:47 +0000 Subject: [PATCH 004/220] MDL-63977 Behat: Add generic way to get tag list --- behat_app.php | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/behat_app.php b/behat_app.php index f5d723dd2..a211dcef9 100644 --- a/behat_app.php +++ b/behat_app.php @@ -29,7 +29,6 @@ require_once(__DIR__ . '/../../behat/behat_base.php'); use Behat\Mink\Exception\DriverException; use Behat\Mink\Exception\ExpectationException; -use Behat\Behat\Hook\Scope\BeforeScenarioScope; /** * Mobile/desktop app steps definitions. @@ -40,9 +39,6 @@ use Behat\Behat\Hook\Scope\BeforeScenarioScope; * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class behat_app extends behat_base { - /** @var bool True if the current scenario has the app tag */ - protected $apptag = false; - /** @var stdClass Object with data about launched Ionic instance (if any) */ protected static $ionicrunning = null; @@ -55,17 +51,6 @@ class behat_app extends behat_base { return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; } - /** - * Checks tags before each scenario. - * - * @BeforeScenario - * @param BeforeScenarioScope $scope Scope information - */ - public function check_tags(BeforeScenarioScope $scope) { - $this->apptag = in_array('app', $scope->getScenario()->getTags()) || - in_array('app', $scope->getFeature()->getTags()); - } - /** * Opens the Moodle app in the browser. * @@ -101,7 +86,7 @@ class behat_app extends behat_base { global $CFG; // Check the app tag was set. - if (!$this->apptag) { + if (!$this->has_tag('app')) { throw new DriverException('Requires @app tag on scenario or feature.'); } From 29bcee1db5f4da92431b07eb82a488e3ea755179 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Tue, 15 Jan 2019 15:12:06 +0000 Subject: [PATCH 005/220] MDL-63977 Behat: Move app startup to before-scenario hook --- behat_app.php | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/behat_app.php b/behat_app.php index a211dcef9..d307f2027 100644 --- a/behat_app.php +++ b/behat_app.php @@ -42,6 +42,9 @@ class behat_app extends behat_base { /** @var stdClass Object with data about launched Ionic instance (if any) */ protected static $ionicrunning = null; + /** @var string URL for running Ionic server */ + protected $ionicurl = ''; + /** * Checks if the current OS is Windows, from the point of view of task-executing-and-killing. * @@ -51,6 +54,17 @@ class behat_app extends behat_base { return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; } + /** + * Called from behat_hooks when a new scenario starts, if it has the app tag. + * + * This updates Moodle configuration and starts Ionic running, if it isn't already. + */ + public function start_scenario() { + $this->check_behat_setup(); + $this->fix_moodle_setup(); + $this->ionicurl = $this->start_or_reuse_ionic(); +} + /** * Opens the Moodle app in the browser. * @@ -62,19 +76,17 @@ class behat_app extends behat_base { * @throws ExpectationException Problem with resizing window */ public function i_enter_the_app() { + // Check the app tag was set. + if (!$this->has_tag('app')) { + throw new DriverException('Requires @app tag on scenario or feature.'); + } + // Restart the browser and set its size. $this->getSession()->restart(); $this->resize_window('360x720', true); - // Prepare setup. - $this->check_behat_setup(); - $this->fix_moodle_setup(); - - // Start Ionic server (or use existing one). - $url = $this->start_or_reuse_ionic(); - // Go to page and prepare browser for app. - $this->prepare_browser($url); + $this->prepare_browser($this->ionicurl); } /** @@ -85,11 +97,6 @@ class behat_app extends behat_base { protected function check_behat_setup() { global $CFG; - // Check the app tag was set. - if (!$this->has_tag('app')) { - throw new DriverException('Requires @app tag on scenario or feature.'); - } - // Check JavaScript is enabled. if (!$this->running_javascript()) { throw new DriverException('The app requires JavaScript.'); From ebe805c8432dfa3bb4f54154bf1f834fa73eb2fa Mon Sep 17 00:00:00 2001 From: sam marshall Date: Tue, 15 Jan 2019 16:51:38 +0000 Subject: [PATCH 006/220] MDL-63977 Behat: Make standard login step work for app as well --- behat_app.php | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/behat_app.php b/behat_app.php index d307f2027..04c63646d 100644 --- a/behat_app.php +++ b/behat_app.php @@ -321,20 +321,18 @@ class behat_app extends behat_base { } /** - * Logs in as the given user in the app's login screen. + * Carries out the login steps for the app, assuming the user is on the app login page. Called + * from behat_auth.php. * - * Must be run from the app login screen (i.e. immediately after first 'I enter the app'). - * - * @Given /^I log in as "(?P(?:[^"]|\\")*)" in the app$/ * @param string $username Username (and password) - * @throws DriverException If the main page doesn't load + * @throws Exception Any error */ - public function i_log_in_as_username_in_the_app(string $username) { + public function login(string $username) { $this->i_set_the_field_in_the_app('Username', $username); $this->i_set_the_field_in_the_app('Password', $username); // Note there are two 'Log in' texts visible (the title and the button) so we have to use - // the 'near' syntax here. + // a 'near' value here. $this->i_press_near_in_the_app('Log in', 'Forgotten'); // Wait until the main page appears. @@ -398,15 +396,7 @@ class behat_app extends behat_base { * @throws DriverException If the press doesn't work */ public function i_press_in_the_app(string $text) { - $this->spin(function($context, $args) use ($text) { - $result = $this->getSession()->evaluateScript('return window.behatPress("' . - addslashes_js($text) . '");'); - if ($result !== 'OK') { - throw new DriverException('Error pressing item - ' . $result); - } - return true; - }); - $this->wait_for_pending_js(); + $this->press($text); } /** @@ -422,9 +412,30 @@ class behat_app extends behat_base { * @throws DriverException If the press doesn't work */ public function i_press_near_in_the_app(string $text, string $near) { + $this->press($text, $near); + } + + /** + * Clicks on / touches something that is visible in the app, near some other text. + * + * If the $near is specified then when there are multiple matches, it picks the one + * nearest (in DOM terms) $near. $near should be an exact match, or a partial match that only + * has one result. + * + * @param behat_base $base Behat context + * @param string $text Text identifying click target + * @param string $near Text identifying a nearby unique piece of text + * @throws DriverException If the press doesn't work + */ + protected function press(string $text, string $near = '') { $this->spin(function($context, $args) use ($text, $near) { - $result = $this->getSession()->evaluateScript('return window.behatPress("' . - addslashes_js($text) . '", "' . addslashes_js($near) . '");'); + if ($near !== '') { + $nearbit = ', "' . addslashes_js($near) . '"'; + } else { + $nearbit = ''; + } + $result = $context->getSession()->evaluateScript('return window.behatPress("' . + addslashes_js($text) . '"' . $nearbit .');'); if ($result !== 'OK') { throw new DriverException('Error pressing item - ' . $result); } From 165c117bcacc47dbe9c3c1b1be02109794f2bc84 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Mon, 11 Feb 2019 16:40:56 +0000 Subject: [PATCH 007/220] MDL-63977 Behat: Rename Ionic config variables for consistency --- behat_app.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/behat_app.php b/behat_app.php index 04c63646d..322d5cf92 100644 --- a/behat_app.php +++ b/behat_app.php @@ -103,8 +103,8 @@ class behat_app extends behat_base { } // Check the config settings are defined. - if (empty($CFG->behat_ionicaddress) && empty($CFG->behat_approot)) { - throw new DriverException('$CFG->behat_ionicaddress or $CFG->behat_approot must be defined.'); + if (empty($CFG->behat_ionic_wwwroot) && empty($CFG->behat_ionic_dirroot)) { + throw new DriverException('$CFG->behat_ionic_wwwroot or $CFG->behat_ionic_dirroot must be defined.'); } } @@ -176,15 +176,15 @@ class behat_app extends behat_base { protected function start_or_reuse_ionic() { global $CFG; - if (!empty($CFG->behat_ionicaddress)) { + if (!empty($CFG->behat_ionic_wwwroot)) { // Use supplied Ionic server which should already be running. - $url = $CFG->behat_ionicaddress; + $url = $CFG->behat_ionic_wwwroot; } else if (self::$ionicrunning) { // Use existing Ionic instance launched previously. $url = self::$ionicrunning->url; } else { // Open Ionic process in relevant path. - $path = realpath($CFG->behat_approot); + $path = realpath($CFG->behat_ionic_dirroot); $stderrfile = $CFG->dataroot . '/behat/ionic-stderr.log'; $prefix = ''; // Except on Windows, use 'exec' so that we get the pid of the actual Node process From c5ce5618abfa310bbbce0698085bbdd10ccfbf95 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Tue, 12 Feb 2019 10:13:51 +0000 Subject: [PATCH 008/220] MDL-63977 Behat: Organise app functions in window.behat object --- app_behat_runtime.js | 19 ++++++++++++++----- behat_app.php | 10 +++++----- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/app_behat_runtime.js b/app_behat_runtime.js index b07b53e63..d88fa92b7 100644 --- a/app_behat_runtime.js +++ b/app_behat_runtime.js @@ -389,7 +389,7 @@ * @param {string} button Type of button to press * @return {string} OK if successful, or ERROR: followed by message */ - window.behatPressStandard = function(button) { + var behatPressStandard = function(button) { log('Action - Click standard button: ' + button); var selector; switch (button) { @@ -438,7 +438,7 @@ * * @return {string} OK if successful, or ERROR: followed by message */ - window.behatClosePopup = function() { + var behatClosePopup = function() { log('Action - Close popup'); var backdrops = Array.from(document.querySelectorAll('ion-backdrop')); @@ -474,7 +474,7 @@ * @param {string} near Optional 'near' text - if specified, must have a single match on page * @return {string} OK if successful, or ERROR: followed by message */ - window.behatPress = function(text, near) { + var behatPress = function(text, near) { log('Action - Press ' + text + (near === undefined ? '' : ' - near ' + near)); var found; @@ -510,7 +510,7 @@ * * @return {string} OK: followed by header text if successful, or ERROR: followed by message. */ - window.behatGetHeader = function() { + var behatGetHeader = function() { log('Action - Get header'); var result = null; @@ -541,7 +541,7 @@ * @param {string} value New value * @return {string} OK or ERROR: followed by message */ - window.behatSetField = function(field, value) { + var behatSetField = function(field, value) { log('Action - Set field ' + field + ' to: ' + value); // Find input(s) with given placeholder. @@ -635,4 +635,13 @@ return 'OK'; }; + + // Make some functions publicly available for Behat to call. + window.behat = { + pressStandard : behatPressStandard, + closePopup : behatClosePopup, + press : behatPress, + setField : behatSetField, + getHeader : behatGetHeader, + }; })(); diff --git a/behat_app.php b/behat_app.php index 322d5cf92..f84b356ee 100644 --- a/behat_app.php +++ b/behat_app.php @@ -358,7 +358,7 @@ class behat_app extends behat_base { */ public function i_press_the_standard_button_in_the_app(string $button) { $this->spin(function($context, $args) use ($button) { - $result = $this->getSession()->evaluateScript('return window.behatPressStandard("' . + $result = $this->getSession()->evaluateScript('return window.behat.pressStandard("' . $button . '");'); if ($result !== 'OK') { throw new DriverException('Error pressing standard button - ' . $result); @@ -376,7 +376,7 @@ class behat_app extends behat_base { */ public function i_close_the_popup_in_the_app() { $this->spin(function($context, $args) { - $result = $this->getSession()->evaluateScript('return window.behatClosePopup();'); + $result = $this->getSession()->evaluateScript('return window.behat.closePopup();'); if ($result !== 'OK') { throw new DriverException('Error closing popup - ' . $result); } @@ -434,7 +434,7 @@ class behat_app extends behat_base { } else { $nearbit = ''; } - $result = $context->getSession()->evaluateScript('return window.behatPress("' . + $result = $context->getSession()->evaluateScript('return window.behat.press("' . addslashes_js($text) . '"' . $nearbit .');'); if ($result !== 'OK') { throw new DriverException('Error pressing item - ' . $result); @@ -457,7 +457,7 @@ class behat_app extends behat_base { */ public function i_set_the_field_in_the_app(string $field, string $value) { $this->spin(function($context, $args) use ($field, $value) { - $result = $this->getSession()->evaluateScript('return window.behatSetField("' . + $result = $this->getSession()->evaluateScript('return window.behat.setField("' . addslashes_js($field) . '", "' . addslashes_js($value) . '");'); if ($result !== 'OK') { throw new DriverException('Error setting field - ' . $result); @@ -479,7 +479,7 @@ class behat_app extends behat_base { */ public function the_header_should_be_in_the_app(string $text) { $result = $this->spin(function($context, $args) { - $result = $this->getSession()->evaluateScript('return window.behatGetHeader();'); + $result = $this->getSession()->evaluateScript('return window.behat.getHeader();'); if (substr($result, 0, 3) !== 'OK:') { throw new DriverException('Error getting header - ' . $result); } From b7804052a836c851d6c5593cbb7a12ffa6033532 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 13 Feb 2019 13:55:34 +0800 Subject: [PATCH 009/220] MDL-63977 Behat: Prefer ionic approot over wwwroot --- behat_app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/behat_app.php b/behat_app.php index f84b356ee..b2251c34b 100644 --- a/behat_app.php +++ b/behat_app.php @@ -176,7 +176,7 @@ class behat_app extends behat_base { protected function start_or_reuse_ionic() { global $CFG; - if (!empty($CFG->behat_ionic_wwwroot)) { + if (empty($CFG->behat_ionic_dirroot) && !empty($CFG->behat_ionic_wwwroot)) { // Use supplied Ionic server which should already be running. $url = $CFG->behat_ionic_wwwroot; } else if (self::$ionicrunning) { From a24f9dc9dfb24063dbc2c5963685747a203819e7 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 13 Feb 2019 14:14:32 +0800 Subject: [PATCH 010/220] MDL-63977 Behat: Wait longer for app login --- behat_app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/behat_app.php b/behat_app.php index b2251c34b..8a5b23813 100644 --- a/behat_app.php +++ b/behat_app.php @@ -307,7 +307,7 @@ class behat_app extends behat_base { return 'mainpage'; } throw new DriverException('Moodle app login URL prompt not found'); - }, false, 30); + }, self::EXTENDED_TIMEOUT, 30); // If it's the login page, we automatically fill in the URL and leave it on the user/pass // page. If it's the main page, we just leave it there. From e9ea931a48096f9e54d67020dc2d1d9214f4cbf2 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Thu, 28 Feb 2019 17:36:30 +0000 Subject: [PATCH 011/220] MDL-64979 Behat: Add option to increase timeouts --- behat_app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/behat_app.php b/behat_app.php index 8a5b23813..fee3f56d9 100644 --- a/behat_app.php +++ b/behat_app.php @@ -307,7 +307,7 @@ class behat_app extends behat_base { return 'mainpage'; } throw new DriverException('Moodle app login URL prompt not found'); - }, self::EXTENDED_TIMEOUT, 30); + }, behat_base::get_extended_timeout(), 30); // If it's the login page, we automatically fill in the URL and leave it on the user/pass // page. If it's the main page, we just leave it there. From d6be9e72330af321ec48fa4e72e14cbbdb53071a Mon Sep 17 00:00:00 2001 From: "Kiet.Chan" Date: Tue, 26 Mar 2019 10:53:31 +0700 Subject: [PATCH 012/220] MDL-65137 behat: Step "I press...the app" should be able to select image --- app_behat_runtime.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app_behat_runtime.js b/app_behat_runtime.js index d88fa92b7..08ccc8c79 100644 --- a/app_behat_runtime.js +++ b/app_behat_runtime.js @@ -239,10 +239,11 @@ // Find all the Aria labels that contain this text. var exactLabelMatches = []; var anyLabelMatches = []; - findPossibleMatches('//*[@aria-label and contains(@aria-label, "' + escapedText + - '")]', function(match) { + findPossibleMatches('//*[@aria-label and contains(@aria-label, "' + escapedText + '")]' + + '| //img[@alt and contains(@alt, "' + escapedText + '")]', function(match) { // Add to array depending on if it's an exact or partial match. - if (match.getAttribute('aria-label').trim() === text) { + var attributeData = match.getAttribute('aria-label') || match.getAttribute('alt'); + if (attributeData.trim() === text) { exactLabelMatches.push(match); } else { anyLabelMatches.push(match); From 5c88846c22ca09ef4e6012f1cd637f688e3a46ed Mon Sep 17 00:00:00 2001 From: Sara Arjona Date: Fri, 7 Jun 2019 13:04:41 +0200 Subject: [PATCH 013/220] Behat app tests for mod choice --- .../tests/behat/app_basic_usage.feature | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 mod/choice/tests/behat/app_basic_usage.feature diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature new file mode 100644 index 000000000..d6054ad60 --- /dev/null +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -0,0 +1,63 @@ +@mod @mod_choice @app @javascript +Feature: Test basic usage in app + In order to participate in the choice while using the mobile app + As a student + I need basic choice functionality to work + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | + | teacher1 | + | student1 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + + Scenario: Student sends their single choice + Given the following "activities" exist: + | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | + | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test single choice name" in the app + And I press "Option 1" in the app + And I press "Option 2" in the app + And I press "Save my choice" in the app + And I should see "Are you sure" + And I press "OK" in the app + Then I should see "Option 1: 0" + And I should see "Option 2: 1" + And I should see "Option 3: 0" + And I should not see "Remove my choice" + + Scenario: Student sends, changes and remove their multi choice + Given the following "activities" exist: + | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | + | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test multi choice name" in the app + And I press "Option 1" in the app + And I press "Option 2" in the app + And I press "Save my choice" in the app + Then I should see "Option 1: 1" + And I should see "Option 2: 1" + And I should see "Option 3: 0" + And I should see "Remove my choice" + And I press "Option 1" in the app + And I press "Option 3" in the app + And I press "Save my choice" in the app + And I should see "Option 1: 0" + And I should see "Option 2: 1" + And I should see "Option 3: 1" + And I press "Remove my choice" in the app + And I should see "Are you sure" + And I press "OK" in the app + And I should not see "Remove my choice" + And I should see "The results are not currently viewable" From e289e3cf89571294fd90efb14019bf7013dd5ac6 Mon Sep 17 00:00:00 2001 From: Sara Arjona Date: Fri, 7 Jun 2019 14:14:18 +0200 Subject: [PATCH 014/220] Move @app tests from core to this plugin It has been decided to have all the @app behat tests centralised on this plugin. These behat tests were created by Sam Marshall and Kiet.Chan. Thanks a lot! --- mod/forum/tests/behat/app_basic_usage.feature | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 mod/forum/tests/behat/app_basic_usage.feature diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature new file mode 100644 index 000000000..1cd4db642 --- /dev/null +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -0,0 +1,62 @@ +@mod @mod_forum @app @javascript +Feature: Test basic usage in app + In order to participate in the forum while using the mobile app + As a student + I need basic forum functionality to work + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | + | student1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | forum | Test forum name | Test forum | C1 | forum | 0 | + + Scenario: Student starts a discussion + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "My happy subject" in the app + And I set the field "Message" to "An awesome message" in the app + And I press "Post to forum" in the app + Then I should see "My happy subject" + And I should see "An awesome message" + + Scenario: Student posts a reply + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject" in the app + And I set the field "Message" to "DiscussionMessage" in the app + And I press "Post to forum" in the app + And I press "DiscussionSubject" in the app + And I press "Reply" in the app + And I set the field "Message" to "ReplyMessage" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionMessage" + And I should see "ReplyMessage" + + Scenario: Test that 'open in browser' works for forum + When I enter the app + And I change viewport size to "360x640" + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press the page menu button in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "Test forum name" + And I should see "Add a new discussion topic" + And I close the browser tab opened by the app + And I press the back button in the app From 8ad1df7a2fe7f75ceb6a53f3aa0f2c3a0ab54cc0 Mon Sep 17 00:00:00 2001 From: Amaia Anabitarte Date: Mon, 27 May 2019 18:37:19 +0200 Subject: [PATCH 015/220] Fixing behat failures on App3.7 --- mod/forum/tests/behat/app_basic_usage.feature | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 1cd4db642..099472334 100644 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -30,6 +30,7 @@ Feature: Test basic usage in app Then I should see "My happy subject" And I should see "An awesome message" + @app_upto3.6.1 Scenario: Student posts a reply When I enter the app And I log in as "student1" @@ -46,6 +47,23 @@ Feature: Test basic usage in app Then I should see "DiscussionMessage" And I should see "ReplyMessage" + @app_from3.7 + Scenario: Student posts a reply + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject" in the app + And I set the field "Message" to "DiscussionMessage" in the app + And I press "Post to forum" in the app + And I press "DiscussionSubject" in the app + And I press "Reply" in the app + And I set the field "Write your reply" to "ReplyMessage" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionMessage" + And I should see "ReplyMessage" + Scenario: Test that 'open in browser' works for forum When I enter the app And I change viewport size to "360x640" From 21803fc7f2b91b0653dbdbf6b8dbdd47bbb6dd59 Mon Sep 17 00:00:00 2001 From: Amaia Anabitarte Date: Fri, 31 May 2019 13:51:17 +0200 Subject: [PATCH 016/220] MDL-65831 behat: New steps to switch offline mode for moodle app behats --- app_behat_runtime.js | 5 ++++- behat_app.php | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app_behat_runtime.js b/app_behat_runtime.js index 08ccc8c79..3c9f3a496 100644 --- a/app_behat_runtime.js +++ b/app_behat_runtime.js @@ -240,9 +240,12 @@ var exactLabelMatches = []; var anyLabelMatches = []; findPossibleMatches('//*[@aria-label and contains(@aria-label, "' + escapedText + '")]' + + '| //a[@title and contains(@title, "' + escapedText + '")]' + '| //img[@alt and contains(@alt, "' + escapedText + '")]', function(match) { // Add to array depending on if it's an exact or partial match. - var attributeData = match.getAttribute('aria-label') || match.getAttribute('alt'); + var attributeData = match.getAttribute('aria-label') || + match.getAttribute('title') || + match.getAttribute('alt'); if (attributeData.trim() === text) { exactLabelMatches.push(match); } else { diff --git a/behat_app.php b/behat_app.php index fee3f56d9..aebbed109 100644 --- a/behat_app.php +++ b/behat_app.php @@ -524,4 +524,15 @@ class behat_app extends behat_base { $this->getSession()->getDriver()->executeScript('window.close()'); $this->getSession()->switchToWindow($names[0]); } + + /** + * Switch navigator online mode. + * + * @Given /^I switch offline mode to "(?P(?:[^"]|\\")*)"$/ + * @param string $offline New value for navigator online mode + * @throws DriverException If the navigator.online mode is not available + */ + public function i_switch_offline_mode(string $offline) { + $this->getSession()->evaluateScript('appProvider.setForceOffline(' . $offline . ');'); + } } From 1b379e34ebf7ea226244474f767a37a1319545dd Mon Sep 17 00:00:00 2001 From: Amaia Anabitarte Date: Tue, 11 Jun 2019 18:35:14 +0200 Subject: [PATCH 017/220] Adding new behat tests for quiz and data for Moodle app --- mod/data/tests/behat/app_data_entries.feature | 199 ++++++++++++++++++ mod/data/tests/behat/app_data_sync.feature | 136 ++++++++++++ .../tests/behat/app_quiz_navigation.feature | 109 ++++++++++ 3 files changed, 444 insertions(+) create mode 100644 mod/data/tests/behat/app_data_entries.feature create mode 100644 mod/data/tests/behat/app_data_sync.feature create mode 100644 mod/quiz/tests/behat/app_quiz_navigation.feature diff --git a/mod/data/tests/behat/app_data_entries.feature b/mod/data/tests/behat/app_data_entries.feature new file mode 100644 index 000000000..793f1fb38 --- /dev/null +++ b/mod/data/tests/behat/app_data_entries.feature @@ -0,0 +1,199 @@ +@mod @mod_data @app @javascript +Feature: Users can manage entries in database activities + In order to populate databases + As a user + I need to add and manage entries to databases + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | student1 | Student | 1 | student1@example.com | + | student2 | Student | 2 | student2@example.com | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | data | Web links | Useful links | C1 | data1 | + And I log in as "teacher1" + And I am on "Course 1" course homepage + And I add a "Text input" field to "Web links" database and I fill the form with: + | Field name | URL | + | Field description | URL link | + And I add a "Text input" field to "Web links" database and I fill the form with: + | Field name | Description | + | Field description | Link description | + And I log out + + Scenario: Students can add entries to a database in the app + Given I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Web links" near "General" in the app + And I should see "No entries in database" + When I press "Add entries" in the app + And I set the field "URL" to "https://moodle.org/" in the app + And I set the field "Description" to "Moodle community site" in the app + And I press "Save" near "Web links" in the app + Then I should see "https://moodle.org/" + And I should see "Moodle community site" + + Scenario: Students can navigate along single entries in the app + Given I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Web links" near "General" in the app + And I press "Add entries" in the app + And I set the field "URL" to "https://moodle.org/" in the app + And I set the field "Description" to "Moodle community site" in the app + And I press "Save" near "Web links" in the app + When I enter the app + And I log in as "student2" + And I press "Course 1" near "Course overview" in the app + And I press "Web links" near "General" in the app + And I press "Add entries" in the app + And I set the field "URL" to "https://moodlecloud.com/" in the app + And I set the field "Description" to "Moodle Cloud" in the app + And I press "Save" near "Web links" in the app + And I press "More" near "Moodle community site" in the app + Then I should see "Moodle community site" + And I should not see "Next" + And I should see "Previous" + And I press "Previous" in the app + And I should see "Moodle Cloud" + And I should see "Next" + And I should not see "Previous" + And I press "Next" in the app + And I should see "Moodle community site" + And I should not see "Moodle Cloud" + And I press "back" near "Web links" in the app + And I should see "Moodle community site" + And I should see "Moodle Cloud" + + Scenario: Students can not edit or delete other user's entries from list and single view in the app + Given I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Web links" near "General" in the app + And I press "Add entries" in the app + And I set the field "URL" to "https://moodle.org/" in the app + And I set the field "Description" to "Moodle community site" in the app + And I press "Save" near "Web links" in the app + When I enter the app + And I log in as "student2" + And I press "Course 1" near "Course overview" in the app + And I press "Web links" near "General" in the app + Then "Edit" "link" should not exist + And "Delete" "link" should not exist + And I press "More" in the app + And "Edit" "link" should not exist + And "Delete" "link" should not exist + + Scenario: Students can edit and delete their own entries from list and single view in the app + Given I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Web links" near "General" in the app + And I press "Add entries" in the app + And I set the field "URL" to "https://moodle.org/" in the app + And I set the field "Description" to "Moodle community site" in the app + And I press "Save" near "Web links" in the app + When I press "Edit" in the app + And I set the field "URL" to "https://moodlecloud.com/" in the app + And I set the field "Description" to "Moodle Cloud" in the app + And I press "Save" near "Web links" in the app + Then I should not see "https://moodle.org/" + And I should not see "Moodle community site" + And I should see "https://moodlecloud.com/" + And I should see "Moodle Cloud" + And I press "Delete" in the app + And I should see "Are you sure you want to delete this entry?" + And I press "Cancel" in the app + And I should see "Moodle Cloud" + And I press "Delete" in the app + And I should see "Are you sure you want to delete this entry?" + And I press "OK" in the app + And I should not see "Moodle Cloud" + And I press "Add entries" in the app + And I set the field "URL" to "https://moodle.org/" in the app + And I set the field "Description" to "Moodle community site" in the app + And I press "Save" near "Web links" in the app + And I press "More" in the app + And I press "Edit" in the app + And I set the field "URL" to "https://moodlecloud.com/" in the app + And I set the field "Description" to "Moodle Cloud" in the app + And I press "Save" near "Web links" in the app + And I should not see "https://moodle.org/" + And I should not see "Moodle community site" + And I should see "https://moodlecloud.com/" + And I should see "Moodle Cloud" + And I press "Delete" in the app + And I should see "Are you sure you want to delete this entry?" + And I press "Cancel" in the app + And I should see "Moodle Cloud" + And I press "Delete" in the app + And I should see "Are you sure you want to delete this entry?" + And I press "OK" in the app + And I should not see "Moodle Cloud" + And I should see "No entries in database" + + Scenario: Teachers can edit and delete students' entries from list view in the app + Given I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Web links" near "General" in the app + And I press "Add entries" in the app + And I set the field "URL" to "https://moodle.org/" in the app + And I set the field "Description" to "Moodle community site" in the app + And I press "Save" near "Web links" in the app + And I press "Add entries" in the app + And I set the field "URL" to "https://telegram.org/" in the app + And I set the field "Description" to "Telegram" in the app + And I press "Save" near "Web links" in the app + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Course overview" in the app + And I press "Web links" near "General" in the app + Then I should see "https://moodle.org/" + And I should see "Moodle community site" + And I press "Edit" near "Moodle community site" in the app + And I set the field "URL" to "https://moodlecloud.com/" in the app + And I set the field "Description" to "Moodle Cloud" in the app + And I press "Save" near "Web links" in the app + And I should not see "https://moodle.org/" + And I should not see "Moodle community site" + And I should see "https://moodlecloud.com/" + And I should see "Moodle Cloud" + And I press "Delete" near "Moodle Cloud" in the app + And I should see "Are you sure you want to delete this entry?" + And I press "Cancel" in the app + And I should see "Moodle Cloud" + And I press "Delete" near "Moodle Cloud" in the app + And I should see "Are you sure you want to delete this entry?" + And I press "OK" in the app + And I should not see "Moodle Cloud" + And I press "More" in the app + And I should see "https://telegram.org/" + And I should see "Telegram" + And I press "Edit" in the app + And I set the field "URL" to "https://moodlecloud.com/" in the app + And I set the field "Description" to "Moodle Cloud" in the app + And I press "Save" near "Web links" in the app + And I should not see "https://telegram.org/" + And I should not see "Telegram" + And I should see "https://moodlecloud.com/" + And I should see "Moodle Cloud" + And I press "Delete" in the app + And I should see "Are you sure you want to delete this entry?" + And I press "Cancel" in the app + And I should see "Moodle Cloud" + And I press "Delete" in the app + And I should see "Are you sure you want to delete this entry?" + And I press "OK" in the app + And I should not see "Moodle Cloud" diff --git a/mod/data/tests/behat/app_data_sync.feature b/mod/data/tests/behat/app_data_sync.feature new file mode 100644 index 000000000..025f1abcc --- /dev/null +++ b/mod/data/tests/behat/app_data_sync.feature @@ -0,0 +1,136 @@ +@mod @mod_data @app @javascript +Feature: Users can store entries in database activities when offline and sync when online + In order to populate databases while offline + As a user + I need to add and manage entries to databases and sync then when online + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | student1 | Student | 1 | student1@example.com | + | student2 | Student | 2 | student2@example.com | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | data | Web links | Useful links | C1 | data1 | + And I log in as "teacher1" + And I am on "Course 1" course homepage + And I add a "Text input" field to "Web links" database and I fill the form with: + | Field name | URL | + | Field description | URL link | + And I add a "Text input" field to "Web links" database and I fill the form with: + | Field name | Description | + | Field description | Link description | + And I log out + + @app_from3.7 + Scenario: Students can add entries to a database in the app while offline + Given I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Web links" near "General" in the app + And I switch offline mode to "true" + And I should see "No entries in database" + When I press "Add entries" in the app + And I set the field "URL" to "https://moodle.org/" in the app + And I set the field "Description" to "Moodle community site" in the app + And I press "Save" near "Web links" in the app + Then I should see "https://moodle.org/" + And I should see "Moodle community site" + And I should see "This Database has offline data to be synchronised" + And I press "back" near "Web links" in the app + And I switch offline mode to "false" + And I press "Web links" near "General" in the app + And I should see "https://moodle.org/" + And I should see "Moodle community site" + And I should not see "This Database has offline data to be synchronised" + + @app_from3.7 + Scenario: Students can edit and delete entries to a database in the app while offline + Given I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Web links" near "General" in the app + And I should see "No entries in database" + And I press "Add entries" in the app + And I set the field "URL" to "https://moodle.org/" in the app + And I set the field "Description" to "Moodle community site" in the app + And I press "Save" near "Web links" in the app + And I should see "https://moodle.org/" + And I should see "Moodle community site" + And I press "Information" in the app + And I press "Download" in the app + And I wait until the page is ready + And I switch offline mode to "true" + When I press "Edit" in the app + And I set the field "URL" to "https://moodlecloud.com/" in the app + And I set the field "Description" to "Moodle Cloud" in the app + And I press "Save" near "Web links" in the app + Then I should not see "https://moodle.org/" + And I should not see "Moodle community site" + And I should see "https://moodlecloud.com/" + And I should see "Moodle Cloud" + And I should see "This Database has offline data to be synchronised" + And I press "back" near "Web links" in the app + And I switch offline mode to "false" + And I press "Web links" near "General" in the app + And I should not see "https://moodle.org/" + And I should not see "Moodle community site" + And I should see "https://moodlecloud.com/" + And I should see "Moodle Cloud" + And I should not see "This Database has offline data to be synchronised" + And I press "Information" in the app + And I press "Refresh" in the app + And I wait until the page is ready + And I switch offline mode to "true" + And I press "Delete" in the app + And I should see "Are you sure you want to delete this entry?" + And I press "OK" in the app + And I should see "https://moodlecloud.com/" + And I should see "Moodle Cloud" + And I should see "This Database has offline data to be synchronised" + And I press "back" near "Web links" in the app + And I switch offline mode to "false" + And I press "Web links" near "General" in the app + And I should not see "https://moodlecloud.com/" + And I should not see "Moodle Cloud" + And I should not see "This Database has offline data to be synchronised" + + @app_from3.7 + Scenario: Students can undo deleting entries to a database in the app while offline + Given I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Web links" near "General" in the app + And I should see "No entries in database" + And I press "Add entries" in the app + And I set the field "URL" to "https://moodle.org/" in the app + And I set the field "Description" to "Moodle community site" in the app + And I press "Save" near "Web links" in the app + And I should see "https://moodle.org/" + And I should see "Moodle community site" + And I press "Information" in the app + And I press "Download" in the app + And I wait until the page is ready + When I switch offline mode to "true" + And I press "Delete" in the app + And I should see "Are you sure you want to delete this entry?" + And I press "OK" in the app + And I should see "https://moodle.org/" + And I should see "Moodle community site" + And I should see "This Database has offline data to be synchronised" + And I press "Restore" in the app + And I press "back" near "Web links" in the app + And I switch offline mode to "false" + And I press "Web links" near "General" in the app + Then I should see "https://moodle.org/" + And I should see "Moodle community site" + And I should not see "This Database has offline data to be synchronised" diff --git a/mod/quiz/tests/behat/app_quiz_navigation.feature b/mod/quiz/tests/behat/app_quiz_navigation.feature new file mode 100644 index 000000000..630ce0feb --- /dev/null +++ b/mod/quiz/tests/behat/app_quiz_navigation.feature @@ -0,0 +1,109 @@ +@mod @mod_quiz @app @javascript +Feature: Attempt a quiz in app + As a student + In order to demonstrate what I know + I need to be able to attempt quizzes + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | + | student1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | + And the following "question categories" exist: + | contextlevel | reference | name | + | Course | C1 | Test questions | + And the following "questions" exist: + | questioncategory | qtype | name | questiontext | + | Test questions | truefalse | TF1 | Text of the first question | + | Test questions | truefalse | TF2 | Text of the second question | + And quiz "Quiz 1" contains the following questions: + | question | page | + | TF1 | 1 | + | TF2 | 2 | + + @app_upto3.7.0 + Scenario: Next and previous navigation in the 3.6 app + Given I enter the app + And I log in as "student1" + When I press "Course 1" near "Course overview" in the app + And I press "Quiz 1" in the app + And I press "Attempt quiz now" in the app + Then I should see "Text of the first question" + And I should not see "Text of the second question" + And I press "Next" near "Question 1" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Previous" near "Question 2" in the app + And I should not see "Text of the second question" + And I should see "Text of the first question" + And I press "Next" near "Quiz 1" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Previous" near "Quiz 1" in the app + And I should not see "Text of the second question" + And I should see "Text of the first question" + And I press "Next" near "Question 1" in the app + And I press "Next" near "Quiz 1" in the app + And I should see "Summary of attempt" + And I press "Return to attempt" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Next" in the app + And I press "Submit all and finish" in the app + And I should see "Once you submit" + And I press "Cancel" near "Once you submit" in the app + And I should see "Summary of attempt" + And I press "Submit all and finish" in the app + And I press "OK" near "Once you submit" in the app + And I should see "Review" + And I press "home" in the app + And I should see "Acceptance test site" + + @app_from3.7.1 + Scenario: Next and previous navigation in the 3.7 app + Given I enter the app + And I log in as "student1" + When I press "Course 1" near "Course overview" in the app + And I press "Quiz 1" in the app + And I press "Attempt quiz now" in the app + Then I should see "Text of the first question" + And I should not see "Text of the second question" + And I press "Next" near "Question 1" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Previous" near "Question 2" in the app + And I should not see "Text of the second question" + And I should see "Text of the first question" + And I press "Next" near "Quiz 1" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Previous" near "Quiz 1" in the app + And I should not see "Text of the second question" + And I should see "Text of the first question" + And I press "Next" near "Question 1" in the app + And I press "Next" near "Quiz 1" in the app + And I should see "Summary of attempt" + And I press "Return to attempt" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Next" in the app + And I press "Submit all and finish" in the app + And I should see "Once you submit" + And I press "Cancel" near "Once you submit" in the app + And I should see "Summary of attempt" + And I press "Submit all and finish" in the app + And I press "OK" near "Once you submit" in the app + And I should see "Review" + And I press "home" in the app + And I should see "Are you sure" + And I should see "OK" + And I press "OK" in the app + And I should see "Acceptance test site" \ No newline at end of file From a14f5dea2128d2812be088744b3f8aa6160b6758 Mon Sep 17 00:00:00 2001 From: John Beedell Date: Tue, 15 Oct 2019 17:14:40 +0100 Subject: [PATCH 018/220] MDL-66918 behat: Behat app step failing --- app_behat_runtime.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app_behat_runtime.js b/app_behat_runtime.js index 3c9f3a496..888a1571b 100644 --- a/app_behat_runtime.js +++ b/app_behat_runtime.js @@ -401,7 +401,9 @@ selector = 'ion-navbar > button.back-button-md'; break; case 'main menu' : - selector = 'page-core-mainmenu .tab-button > ion-icon[aria-label=more]'; + // Change in app version 3.8. + selector = 'page-core-mainmenu .tab-button > ion-icon[aria-label=more], ' + + 'page-core-mainmenu .tab-button > ion-icon[aria-label=menu]'; break; case 'page menu' : // This lang string was changed in app version 3.6. From 2ea009c474eaf1dd1695f16c081e0cff1bc09761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 11 Dec 2019 11:51:52 +0100 Subject: [PATCH 019/220] MOBILE-3295 behat: Behat basic test for forum --- mod/forum/tests/behat/app_basic_usage.feature | 157 +++++++++++++++++- 1 file changed, 156 insertions(+), 1 deletion(-) mode change 100644 => 100755 mod/forum/tests/behat/app_basic_usage.feature diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature old mode 100644 new mode 100755 index 099472334..02dd888bf --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -11,12 +11,16 @@ Feature: Test basic usage in app And the following "users" exist: | username | | student1 | + | teacher1 | + | teacher2 | And the following "course enrolments" exist: | user | course | role | | student1 | C1 | student | + | teacher1 | C1 | editingteacher | + | teacher2 | C1 | editingteacher | And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | - | forum | Test forum name | Test forum | C1 | forum | 0 | + | forum | Test forum name | Test forum | C1 | forum | 0 | Scenario: Student starts a discussion When I enter the app @@ -78,3 +82,154 @@ Feature: Test basic usage in app And I should see "Add a new discussion topic" And I close the browser tab opened by the app And I press the back button in the app + + @mobile @latest + Scenario: Student star a discussion + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test star" in the app + And I set the field "Message" to "Auto-test star message" in the app + And I press "Post to forum" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test" in the app + And I set the field "Message" to "Auto-test message" in the app + And I press "Post to forum" in the app + And I press "Auto-test star" in the app + And I wait "1" seconds + And I press "Information" in the app + And I press "Star this discussion" in the app + And I press "arrow back" in the app + And I should see "Auto-test star" + And I should see "Auto-test" + And I pause + And I press "Auto-test star" in the app + And I wait "1" seconds + And I press "Information" in the app + And I press "Unstar this discussion" in the app + And I press "arrow back" in the app + Then I should see "Auto-test star" + And I should see "Auto-test" + And I pause + + + @mobile @latest + Scenario: Teacher star and pin a discussion + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test star" in the app + And I set the field "Message" to "Auto-test star message" in the app + And I press "Post to forum" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test pin" in the app + And I set the field "Message" to "Auto-test pin message" in the app + And I press "Post to forum" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test" in the app + And I set the field "Message" to "Auto-test message" in the app + And I press "Post to forum" in the app + And I press "Auto-test star" in the app + And I wait "1" seconds + And I press "Information" in the app + And I press "Star this discussion" in the app + And I press "arrow back" in the app + And I press "Auto-test pin" in the app + And I wait "1" seconds + And I press "Information" in the app + And I press "Pin this discussion" in the app + And I press "arrow back" in the app + And I should see "Auto-test pin" + And I should see "Auto-test star" + And I should see "Auto-test" + And I pause + And I press "Auto-test pin" in the app + And I wait "1" seconds + And I press "Information" in the app + And I press "Unpin this discussion" in the app + And I press "arrow back" in the app + And I press "Auto-test star" in the app + And I wait "1" seconds + And I press "Information" in the app + And I press "Unstar this discussion" in the app + And I press "arrow back" in the app + Then I should see "Auto-test star" + And I should see "Auto-test pin" + And I pause + +@mobile @3.6 @OK + Scenario: Teacher checks pin and star in 3.6 + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test" in the app + And I set the field "Message" to "Auto-test message" in the app + And I press "Post to forum" in the app + And I press "Auto-test" in the app + And I wait "1" seconds + And I press "Information" in the app + Then I should not see "Star this discussion" + And I should not see "Pin this discussion" + + + @mobile + Scenario: Edit a forum post (only online) + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test" in the app + And I set the field "Message" to "Auto-test message" in the app + And I press "Post to forum" in the app + Then I should see "Auto-test" + And I should see "Auto-test message" + And I press "Auto-test" in the app + And I press "Auto-test message" in the app + And I press "Information" in the app + And I pause + And I pause + And I press "Information" near "Test forum name" in the app + And I switch to the browser tab opened by the app + And I log in as "admin" + And I press "Actions menu" + And I follow "Edit settings" + And I press "Ratings" + + + @mobile @latest + Scenario: Add/view ratings + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test" in the app + And I set the field "Message" to "Auto-test message" in the app + And I press "Post to forum" in the app + And I pause + And I press "Information" near "Test forum name" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "admin" + And I press "Actions menu" + And I follow "Edit settings" + And I press "Ratings" + And I press "No ratings" + And I press "Average of ratings" + And I press "None" + And I press "Point" + And I press "Save and display" + And I pause + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "Auto-test" in the app + And I pause From df1e61a955b87be7562ddf25576ddf551a8b36b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 11 Dec 2019 12:03:05 +0100 Subject: [PATCH 020/220] MOBILE-3296 behat: Behat basic test for choice --- .../tests/behat/app_advance_usage.feature | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 mod/choice/tests/behat/app_advance_usage.feature diff --git a/mod/choice/tests/behat/app_advance_usage.feature b/mod/choice/tests/behat/app_advance_usage.feature new file mode 100644 index 000000000..3692e125e --- /dev/null +++ b/mod/choice/tests/behat/app_advance_usage.feature @@ -0,0 +1,63 @@ +@mod @mod_choice @app @javascript +Feature: Test basic usage in app + In order to participate in the choice while using the mobile app + As a student + I need basic choice functionality to work + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | + | teacher1 | + | student1 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + + Scenario: Student sends their single choice + Given the following "activities" exist: + | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | + | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test single choice name" in the app + And I press "Option 1" in the app + And I press "Option 2" in the app + And I press "Save my choice" in the app + And I should see "Are you sure" + And I press "OK" in the app + Then I should see "Option 1: 0" + And I should see "Option 2: 1" + And I should see "Option 3: 0" + And I should not see "Remove my choice" + + Scenario: Student sends, changes and remove their multi choice + Given the following "activities" exist: + | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | + | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test multi choice name" in the app + And I press "Option 1" in the app + And I press "Option 2" in the app + And I press "Save my choice" in the app + Then I should see "Option 1: 1" + And I should see "Option 2: 1" + And I should see "Option 3: 0" + And I should see "Remove my choice" + And I press "Option 1" in the app + And I press "Option 3" in the app + And I press "Save my choice" in the app + And I should see "Option 1: 0" + And I should see "Option 2: 1" + And I should see "Option 3: 1" + And I press "Remove my choice" in the app + And I should see "Are you sure" + And I press "OK" in the app + And I should not see "Remove my choice" + And I should see "The results are not currently viewable" \ No newline at end of file From ca18c677e21dfcde301fc5ca1256415d1b6d8529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Fri, 13 Dec 2019 11:47:53 +0100 Subject: [PATCH 021/220] MOBILE-3297 behat: Behat basic test for survey --- mod/choice/tests/behat/MyChoiceTest.feature | 63 ++++++ .../tests/behat/app_basic_usage.feature | 70 ++++-- mod/data/tests/behat/app_data_entries.feature | 199 ++---------------- mod/data/tests/behat/app_data_sync.feature | 0 mod/data/tests/behat/try1.feature | 46 ++++ .../tests/behat/app_quiz_navigation.feature | 1 + mod/quiz/tests/behat/my_quiz_test.feature | 68 ++++++ mod/quiz/tests/behat/tryquiz.feature | 70 ++++++ .../tests/behat/app_basic_usage.feature | 86 ++++++++ 9 files changed, 414 insertions(+), 189 deletions(-) create mode 100755 mod/choice/tests/behat/MyChoiceTest.feature mode change 100644 => 100755 mod/choice/tests/behat/app_basic_usage.feature mode change 100644 => 100755 mod/data/tests/behat/app_data_entries.feature mode change 100644 => 100755 mod/data/tests/behat/app_data_sync.feature create mode 100755 mod/data/tests/behat/try1.feature mode change 100644 => 100755 mod/quiz/tests/behat/app_quiz_navigation.feature create mode 100755 mod/quiz/tests/behat/my_quiz_test.feature create mode 100755 mod/quiz/tests/behat/tryquiz.feature create mode 100755 mod/survey/tests/behat/app_basic_usage.feature diff --git a/mod/choice/tests/behat/MyChoiceTest.feature b/mod/choice/tests/behat/MyChoiceTest.feature new file mode 100755 index 000000000..3692e125e --- /dev/null +++ b/mod/choice/tests/behat/MyChoiceTest.feature @@ -0,0 +1,63 @@ +@mod @mod_choice @app @javascript +Feature: Test basic usage in app + In order to participate in the choice while using the mobile app + As a student + I need basic choice functionality to work + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | + | teacher1 | + | student1 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + + Scenario: Student sends their single choice + Given the following "activities" exist: + | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | + | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test single choice name" in the app + And I press "Option 1" in the app + And I press "Option 2" in the app + And I press "Save my choice" in the app + And I should see "Are you sure" + And I press "OK" in the app + Then I should see "Option 1: 0" + And I should see "Option 2: 1" + And I should see "Option 3: 0" + And I should not see "Remove my choice" + + Scenario: Student sends, changes and remove their multi choice + Given the following "activities" exist: + | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | + | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test multi choice name" in the app + And I press "Option 1" in the app + And I press "Option 2" in the app + And I press "Save my choice" in the app + Then I should see "Option 1: 1" + And I should see "Option 2: 1" + And I should see "Option 3: 0" + And I should see "Remove my choice" + And I press "Option 1" in the app + And I press "Option 3" in the app + And I press "Save my choice" in the app + And I should see "Option 1: 0" + And I should see "Option 2: 1" + And I should see "Option 3: 1" + And I press "Remove my choice" in the app + And I should see "Are you sure" + And I press "OK" in the app + And I should not see "Remove my choice" + And I should see "The results are not currently viewable" \ No newline at end of file diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature old mode 100644 new mode 100755 index d6054ad60..6f04b01a5 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -5,19 +5,27 @@ Feature: Test basic usage in app I need basic choice functionality to work Background: - Given the following "courses" exist: - | fullname | shortname | - | Course 1 | C1 | - And the following "users" exist: - | username | - | teacher1 | - | student1 | + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student | student | student1@example.com | + | student2 | Student | 2 | student2@example.com | + | student3 | Student | 3 | student3@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + | student3 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | option | + | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | - Scenario: Student sends their single choice + @3.8.0 @OK + Scenario: Student sends their single choice, views results and sync. Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | @@ -34,8 +42,17 @@ Feature: Test basic usage in app And I should see "Option 2: 1" And I should see "Option 3: 0" And I should not see "Remove my choice" + And I pause + And I press "arrow back" in the app + And I press "Test single choice name" in the app + And I should see "Option 1: 0" + And I should see "Option 2: 1" + And I should see "Option 3: 0" + And I + And I pause - Scenario: Student sends, changes and remove their multi choice + @3.8.0 @OK + Scenario: Student sends, changes and remove their multi choice Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | @@ -58,6 +75,33 @@ Feature: Test basic usage in app And I should see "Option 3: 1" And I press "Remove my choice" in the app And I should see "Are you sure" - And I press "OK" in the app + And I press "Delete" in the app And I should not see "Remove my choice" And I should see "The results are not currently viewable" + + + @3.8.0 @OK + Scenario: Download student choice in text format + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Choice name" in the app + And I press "Option 1" in the app + And I press "Option 2" in the app + And I press "Save my choice" in the app + And I should see "Are you sure" + And I press "OK" in the app + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Course overview" in the app + And I press "Choice name" in the app + And I press "Information" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "View 1 responses" + And I press "Download in text format" + And I close the browser tab opened by the app + + diff --git a/mod/data/tests/behat/app_data_entries.feature b/mod/data/tests/behat/app_data_entries.feature old mode 100644 new mode 100755 index 793f1fb38..2517342ef --- a/mod/data/tests/behat/app_data_entries.feature +++ b/mod/data/tests/behat/app_data_entries.feature @@ -1,8 +1,5 @@ @mod @mod_data @app @javascript -Feature: Users can manage entries in database activities - In order to populate databases - As a user - I need to add and manage entries to databases +Feature: Trying options moodle mobile Background: Given the following "users" exist: @@ -21,179 +18,29 @@ Feature: Users can manage entries in database activities And the following "activities" exist: | activity | name | intro | course | idnumber | | data | Web links | Useful links | C1 | data1 | - And I log in as "teacher1" - And I am on "Course 1" course homepage - And I add a "Text input" field to "Web links" database and I fill the form with: - | Field name | URL | - | Field description | URL link | - And I add a "Text input" field to "Web links" database and I fill the form with: - | Field name | Description | - | Field description | Link description | - And I log out - - Scenario: Students can add entries to a database in the app + + Scenario: Teacher create an event Given I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Web links" near "General" in the app - And I should see "No entries in database" - When I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - Then I should see "https://moodle.org/" - And I should see "Moodle community site" + When I log in as "teacher1" + And I press "calendar" in the app + And I press "close" in the app + And I set the field "name" to "Holidays!" + And I press "No selection" in the app + And I press "Course 1" in the app + Then I press "Show more..." in the app + And I set the field "location" to "Moodle" + And I press "Save" in the app - Scenario: Students can navigate along single entries in the app + Scenario: Student change his moodle language Given I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Web links" near "General" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - When I enter the app - And I log in as "student2" - And I press "Course 1" near "Course overview" in the app - And I press "Web links" near "General" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - And I press "More" near "Moodle community site" in the app - Then I should see "Moodle community site" - And I should not see "Next" - And I should see "Previous" - And I press "Previous" in the app - And I should see "Moodle Cloud" - And I should see "Next" - And I should not see "Previous" - And I press "Next" in the app - And I should see "Moodle community site" - And I should not see "Moodle Cloud" - And I press "back" near "Web links" in the app - And I should see "Moodle community site" - And I should see "Moodle Cloud" + When I log in as "student1" + And I press "more" near "Timeline" in the app + And I press "App settings" in the app + And I press "General" in the app + And I press "Language" in the app + And I press "Español" in the app + And I pause + And I press "Text size" near "Español" in the app + And I pause + - Scenario: Students can not edit or delete other user's entries from list and single view in the app - Given I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Web links" near "General" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - When I enter the app - And I log in as "student2" - And I press "Course 1" near "Course overview" in the app - And I press "Web links" near "General" in the app - Then "Edit" "link" should not exist - And "Delete" "link" should not exist - And I press "More" in the app - And "Edit" "link" should not exist - And "Delete" "link" should not exist - - Scenario: Students can edit and delete their own entries from list and single view in the app - Given I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Web links" near "General" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - When I press "Edit" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - Then I should not see "https://moodle.org/" - And I should not see "Moodle community site" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Cancel" in the app - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app - And I should not see "Moodle Cloud" - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - And I press "More" in the app - And I press "Edit" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - And I should not see "https://moodle.org/" - And I should not see "Moodle community site" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Cancel" in the app - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app - And I should not see "Moodle Cloud" - And I should see "No entries in database" - - Scenario: Teachers can edit and delete students' entries from list view in the app - Given I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Web links" near "General" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://telegram.org/" in the app - And I set the field "Description" to "Telegram" in the app - And I press "Save" near "Web links" in the app - When I enter the app - And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app - And I press "Web links" near "General" in the app - Then I should see "https://moodle.org/" - And I should see "Moodle community site" - And I press "Edit" near "Moodle community site" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - And I should not see "https://moodle.org/" - And I should not see "Moodle community site" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I press "Delete" near "Moodle Cloud" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Cancel" in the app - And I should see "Moodle Cloud" - And I press "Delete" near "Moodle Cloud" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app - And I should not see "Moodle Cloud" - And I press "More" in the app - And I should see "https://telegram.org/" - And I should see "Telegram" - And I press "Edit" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - And I should not see "https://telegram.org/" - And I should not see "Telegram" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Cancel" in the app - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app - And I should not see "Moodle Cloud" diff --git a/mod/data/tests/behat/app_data_sync.feature b/mod/data/tests/behat/app_data_sync.feature old mode 100644 new mode 100755 diff --git a/mod/data/tests/behat/try1.feature b/mod/data/tests/behat/try1.feature new file mode 100755 index 000000000..295e8b099 --- /dev/null +++ b/mod/data/tests/behat/try1.feature @@ -0,0 +1,46 @@ +@mod @mod_data @app @javascript +Feature: Trying options moodle mobile + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | student1 | Student | 1 | student1@example.com | + | student2 | Student | 2 | student2@example.com | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | data | Web links | Useful links | C1 | data1 | + + Scenario: Teacher create an event + When I enter the app + And I log in as "teacher1" + And I press "calendar" in the app + And I press "close" in the app + And I set the field "name" to "Holidays!" + And I press "No selection" in the app + And I press "Course 1" in the app + Then I press "Show more..." in the app + And I set the field "location" to "Moodle" + And I press "Save" in the app + + Scenario: Student change his moodle language + When I enter the app + And I log in as "student1" + And I press "more" near "Timeline" in the app + And I press "App settings" in the app + And I press "General" in the app + And I press "Language" in the app + And I press "Español" in the app + And I pause + And I press "Text size" in the app + And I pause + + diff --git a/mod/quiz/tests/behat/app_quiz_navigation.feature b/mod/quiz/tests/behat/app_quiz_navigation.feature old mode 100644 new mode 100755 index 630ce0feb..63c0e71be --- a/mod/quiz/tests/behat/app_quiz_navigation.feature +++ b/mod/quiz/tests/behat/app_quiz_navigation.feature @@ -106,4 +106,5 @@ Feature: Attempt a quiz in app And I should see "Are you sure" And I should see "OK" And I press "OK" in the app + And I pause And I should see "Acceptance test site" \ No newline at end of file diff --git a/mod/quiz/tests/behat/my_quiz_test.feature b/mod/quiz/tests/behat/my_quiz_test.feature new file mode 100755 index 000000000..23130378b --- /dev/null +++ b/mod/quiz/tests/behat/my_quiz_test.feature @@ -0,0 +1,68 @@ +@mod @mod_quiz @app @javascript +Feature: Attempt a quiz in app + As a student + In order to demonstrate what I know + I need to be able to attempt quizzes + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | + | student1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | + And the following "question categories" exist: + | contextlevel | reference | name | + | Course | C1 | Test questions | + And the following "questions" exist: + | questioncategory | qtype | name | questiontext | + | Test questions | truefalse | TF1 | Text of the first question | + | Test questions | truefalse | TF2 | Text of the second question | + And quiz "Quiz 1" contains the following questions: + | question | page | + | TF1 | 1 | + | TF2 | 2 | + + @app_upto3.7.0 + Scenario: Next and previous navigation in the 3.6 app + Given I enter the app + And I log in as "student1" + When I press "Course 1" near "Course overview" in the app + And I press "Quiz 1" in the app + And I press "Attempt quiz now" in the app + Then I should see "Text of the first question" + And I should not see "Text of the second question" + And I press "Next" near "Question 1" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Previous" near "Question 2" in the app + And I should not see "Text of the second question" + And I should see "Text of the first question" + And I press "Next" near "Quiz 1" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Previous" near "Quiz 1" in the app + And I should not see "Text of the second question" + And I should see "Text of the first question" + And I press "Next" near "Question 1" in the app + And I press "Next" near "Quiz 1" in the app + And I should see "Summary of attempt" + And I press "Return to attempt" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Next" in the app + And I press "Submit all and finish" in the app + And I should see "Once you submit" + And I press "Cancel" near "Once you submit" in the app + And I should see "Summary of attempt" + And I press "Submit all and finish" in the app + And I press "OK" near "Once you submit" in the app + And I should see "Review" + And I press "home" in the app + And I should see "Acceptance test site" \ No newline at end of file diff --git a/mod/quiz/tests/behat/tryquiz.feature b/mod/quiz/tests/behat/tryquiz.feature new file mode 100755 index 000000000..dd633b92a --- /dev/null +++ b/mod/quiz/tests/behat/tryquiz.feature @@ -0,0 +1,70 @@ +@mod @mod_quiz @app @javascript +Feature: Trying quizzes in app + As a student + In order to demonstrate what I know + I need to be able to attempt quizzes + As a teacher + I need to see the results + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | + | student1 | + | teacher1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | teacher1 | C1 | teacher | + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | + And the following "question categories" exist: + | contextlevel | reference | name | + | Course | C1 | Test questions | + And the following "questions" exist: + | questioncategory | qtype | name | questiontext | + | Test questions | truefalse | TF1 | Text of the first question | + | Test questions | truefalse | TF2 | Text of the second question | + And quiz "Quiz 1" contains the following questions: + | question | page | + | TF1 | 1 | + | TF2 | 2 | + + @app_from3.7.1 + Scenario: Student attempt a quiz in app and teacher see the results. + Given I enter the app + And I log in as "student1" + When I press "Course 1" near "Course overview" in the app + And I press "Quiz 1" in the app + And I press "Attempt quiz now" in the app + Then I should see "Text of the first question" + And I should not see "Text of the second question" + And I press "True" in the app + And I press "Next" near "Question 1" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "False" in the app + And I press "Clear my choice" in the app + And I press "True" in the app + And I press "Next" in the app + And I press "Submit all and finish" in the app + And I should see "OK" + And I press "OK" in the app + And I should see "Review" + Given I enter the app + And I log in as "teacher1" + When I press "Course 1" near "Course overview" in the app + And I press "Quiz 1" in the app + And I press "Information" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "Results" + And I press "Download" + And I pause + And I close the browser tab opened by the app + \ No newline at end of file diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature new file mode 100755 index 000000000..957c2fd09 --- /dev/null +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -0,0 +1,86 @@ +@mod @mod_survey @app @javascript +Feature: Test basic usage in app + In order to participate in surveys while using the mobile app + As a student + I need basic forum functionality to work + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | + | student1 | + | teacher1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | teacher1 | C1 | editingteacher | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | survey | Test survey name | Test survey | C1 | survey | 0 | + + @Mobile @3.8.0 @OK + Scenario: Student answer a survey and see results + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey name" in the app + And I press "Choose" near "1. In evaluating what someone says, I focus on the quality of their argument, not on the person who's presenting it." in the app + And I press "Strongly agree" in the app + And I press "Choose" near "2. I like playing devil's advocate - arguing the opposite of what someone is saying." in the app + And I press "Strongly disagree" in the app + And I press "Choose" near "3. I like to understand where other people are 'coming from', what experiences have led them to feel the way they do." in the app + And I press "Somewhat agree" in the app + And I press "Choose" near "4. The most important part of my education has been learning to understand people who are very different to me." in the app + And I press "Somewhat disagree" in the app + And I press "Choose" near "5. I feel that the best way for me to achieve my own identity is to interact with a variety of other people." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "6. I enjoy hearing the opinions of people who come from backgrounds different to mine - it helps me to understand how the same things can be seen in such different ways." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "7. I find that I can strengthen my own position through arguing with someone who disagrees with me." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "8. I am always interested in knowing why people say and believe the things they do." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "9. I often find myself arguing with the authors of books that I read, trying to logically figure out why they're wrong." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "10. It's important for me to remain as objective as possible when I analyze something." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "11. I try to think with people instead of against them." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "12. I have certain criteria I use in evaluating arguments." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "13. I'm more likely to try to understand someone else's opinion than to try to evaluate it." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "14. I try to point out weaknesses in other people's thinking to help them clarify their arguments." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "15. I tend to put myself in other people's shoes when discussing controversial issues, to see why they think the way they do." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "16. One could call my way of analysing things 'putting them on trial' because I am careful to consider all the evidence." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "17. I value the use of logic and reason over the incorporation of my own concerns when solving problems." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "18. I can obtain insight into opinions that differ from mine through empathy." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "19. When I encounter people whose opinions seem alien to me, I make a deliberate effort to 'extend' myself into that person, to try to see how they could have those opinions." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "20. I spend time figuring out what's 'wrong' with things. For example, I'll look for something in a literary interpretation that isn't argued well enough." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Submit" in the app + And I press "OK" in the app + And I press "open" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" + + @Tablet @3.8.0 + Scenario: Student answer a survey and see results tablet + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey name" in the app + And I pause + + From a9da44ebeba0667a7d135e387c8ac8ad2380fac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Fri, 13 Dec 2019 12:16:40 +0100 Subject: [PATCH 022/220] MOBILE-3296 behat: Behat basic test for choice --- mod/choice/tests/behat/MyChoiceTest.feature | 63 ----------------- .../tests/behat/app_advance_usage.feature | 63 ----------------- .../tests/behat/app_basic_usage.feature | 6 +- mod/data/tests/behat/try1.feature | 46 ------------ mod/quiz/tests/behat/my_quiz_test.feature | 68 ------------------ mod/quiz/tests/behat/tryquiz.feature | 70 ------------------- 6 files changed, 1 insertion(+), 315 deletions(-) delete mode 100755 mod/choice/tests/behat/MyChoiceTest.feature delete mode 100644 mod/choice/tests/behat/app_advance_usage.feature delete mode 100755 mod/data/tests/behat/try1.feature delete mode 100755 mod/quiz/tests/behat/my_quiz_test.feature delete mode 100755 mod/quiz/tests/behat/tryquiz.feature diff --git a/mod/choice/tests/behat/MyChoiceTest.feature b/mod/choice/tests/behat/MyChoiceTest.feature deleted file mode 100755 index 3692e125e..000000000 --- a/mod/choice/tests/behat/MyChoiceTest.feature +++ /dev/null @@ -1,63 +0,0 @@ -@mod @mod_choice @app @javascript -Feature: Test basic usage in app - In order to participate in the choice while using the mobile app - As a student - I need basic choice functionality to work - - Background: - Given the following "courses" exist: - | fullname | shortname | - | Course 1 | C1 | - And the following "users" exist: - | username | - | teacher1 | - | student1 | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - - Scenario: Student sends their single choice - Given the following "activities" exist: - | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | - | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test single choice name" in the app - And I press "Option 1" in the app - And I press "Option 2" in the app - And I press "Save my choice" in the app - And I should see "Are you sure" - And I press "OK" in the app - Then I should see "Option 1: 0" - And I should see "Option 2: 1" - And I should see "Option 3: 0" - And I should not see "Remove my choice" - - Scenario: Student sends, changes and remove their multi choice - Given the following "activities" exist: - | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | - | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test multi choice name" in the app - And I press "Option 1" in the app - And I press "Option 2" in the app - And I press "Save my choice" in the app - Then I should see "Option 1: 1" - And I should see "Option 2: 1" - And I should see "Option 3: 0" - And I should see "Remove my choice" - And I press "Option 1" in the app - And I press "Option 3" in the app - And I press "Save my choice" in the app - And I should see "Option 1: 0" - And I should see "Option 2: 1" - And I should see "Option 3: 1" - And I press "Remove my choice" in the app - And I should see "Are you sure" - And I press "OK" in the app - And I should not see "Remove my choice" - And I should see "The results are not currently viewable" \ No newline at end of file diff --git a/mod/choice/tests/behat/app_advance_usage.feature b/mod/choice/tests/behat/app_advance_usage.feature deleted file mode 100644 index 3692e125e..000000000 --- a/mod/choice/tests/behat/app_advance_usage.feature +++ /dev/null @@ -1,63 +0,0 @@ -@mod @mod_choice @app @javascript -Feature: Test basic usage in app - In order to participate in the choice while using the mobile app - As a student - I need basic choice functionality to work - - Background: - Given the following "courses" exist: - | fullname | shortname | - | Course 1 | C1 | - And the following "users" exist: - | username | - | teacher1 | - | student1 | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - - Scenario: Student sends their single choice - Given the following "activities" exist: - | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | - | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test single choice name" in the app - And I press "Option 1" in the app - And I press "Option 2" in the app - And I press "Save my choice" in the app - And I should see "Are you sure" - And I press "OK" in the app - Then I should see "Option 1: 0" - And I should see "Option 2: 1" - And I should see "Option 3: 0" - And I should not see "Remove my choice" - - Scenario: Student sends, changes and remove their multi choice - Given the following "activities" exist: - | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | - | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test multi choice name" in the app - And I press "Option 1" in the app - And I press "Option 2" in the app - And I press "Save my choice" in the app - Then I should see "Option 1: 1" - And I should see "Option 2: 1" - And I should see "Option 3: 0" - And I should see "Remove my choice" - And I press "Option 1" in the app - And I press "Option 3" in the app - And I press "Save my choice" in the app - And I should see "Option 1: 0" - And I should see "Option 2: 1" - And I should see "Option 3: 1" - And I press "Remove my choice" in the app - And I should see "Are you sure" - And I press "OK" in the app - And I should not see "Remove my choice" - And I should see "The results are not currently viewable" \ No newline at end of file diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 6f04b01a5..dc3d45e7e 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -25,7 +25,7 @@ Feature: Test basic usage in app | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | @3.8.0 @OK - Scenario: Student sends their single choice, views results and sync. + Scenario: Student sends their single choice and views results. Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | @@ -42,14 +42,11 @@ Feature: Test basic usage in app And I should see "Option 2: 1" And I should see "Option 3: 0" And I should not see "Remove my choice" - And I pause And I press "arrow back" in the app And I press "Test single choice name" in the app And I should see "Option 1: 0" And I should see "Option 2: 1" And I should see "Option 3: 0" - And I - And I pause @3.8.0 @OK Scenario: Student sends, changes and remove their multi choice @@ -104,4 +101,3 @@ Feature: Test basic usage in app And I press "Download in text format" And I close the browser tab opened by the app - diff --git a/mod/data/tests/behat/try1.feature b/mod/data/tests/behat/try1.feature deleted file mode 100755 index 295e8b099..000000000 --- a/mod/data/tests/behat/try1.feature +++ /dev/null @@ -1,46 +0,0 @@ -@mod @mod_data @app @javascript -Feature: Trying options moodle mobile - - Background: - Given the following "users" exist: - | username | firstname | lastname | email | - | student1 | Student | 1 | student1@example.com | - | student2 | Student | 2 | student2@example.com | - | teacher1 | Teacher | 1 | teacher1@example.com | - And the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - | student2 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | data | Web links | Useful links | C1 | data1 | - - Scenario: Teacher create an event - When I enter the app - And I log in as "teacher1" - And I press "calendar" in the app - And I press "close" in the app - And I set the field "name" to "Holidays!" - And I press "No selection" in the app - And I press "Course 1" in the app - Then I press "Show more..." in the app - And I set the field "location" to "Moodle" - And I press "Save" in the app - - Scenario: Student change his moodle language - When I enter the app - And I log in as "student1" - And I press "more" near "Timeline" in the app - And I press "App settings" in the app - And I press "General" in the app - And I press "Language" in the app - And I press "Español" in the app - And I pause - And I press "Text size" in the app - And I pause - - diff --git a/mod/quiz/tests/behat/my_quiz_test.feature b/mod/quiz/tests/behat/my_quiz_test.feature deleted file mode 100755 index 23130378b..000000000 --- a/mod/quiz/tests/behat/my_quiz_test.feature +++ /dev/null @@ -1,68 +0,0 @@ -@mod @mod_quiz @app @javascript -Feature: Attempt a quiz in app - As a student - In order to demonstrate what I know - I need to be able to attempt quizzes - - Background: - Given the following "courses" exist: - | fullname | shortname | - | Course 1 | C1 | - And the following "users" exist: - | username | - | student1 | - And the following "course enrolments" exist: - | user | course | role | - | student1 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | - And the following "question categories" exist: - | contextlevel | reference | name | - | Course | C1 | Test questions | - And the following "questions" exist: - | questioncategory | qtype | name | questiontext | - | Test questions | truefalse | TF1 | Text of the first question | - | Test questions | truefalse | TF2 | Text of the second question | - And quiz "Quiz 1" contains the following questions: - | question | page | - | TF1 | 1 | - | TF2 | 2 | - - @app_upto3.7.0 - Scenario: Next and previous navigation in the 3.6 app - Given I enter the app - And I log in as "student1" - When I press "Course 1" near "Course overview" in the app - And I press "Quiz 1" in the app - And I press "Attempt quiz now" in the app - Then I should see "Text of the first question" - And I should not see "Text of the second question" - And I press "Next" near "Question 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Previous" near "Question 2" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" - And I press "Next" near "Quiz 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Previous" near "Quiz 1" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" - And I press "Next" near "Question 1" in the app - And I press "Next" near "Quiz 1" in the app - And I should see "Summary of attempt" - And I press "Return to attempt" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Next" in the app - And I press "Submit all and finish" in the app - And I should see "Once you submit" - And I press "Cancel" near "Once you submit" in the app - And I should see "Summary of attempt" - And I press "Submit all and finish" in the app - And I press "OK" near "Once you submit" in the app - And I should see "Review" - And I press "home" in the app - And I should see "Acceptance test site" \ No newline at end of file diff --git a/mod/quiz/tests/behat/tryquiz.feature b/mod/quiz/tests/behat/tryquiz.feature deleted file mode 100755 index dd633b92a..000000000 --- a/mod/quiz/tests/behat/tryquiz.feature +++ /dev/null @@ -1,70 +0,0 @@ -@mod @mod_quiz @app @javascript -Feature: Trying quizzes in app - As a student - In order to demonstrate what I know - I need to be able to attempt quizzes - As a teacher - I need to see the results - - Background: - Given the following "courses" exist: - | fullname | shortname | - | Course 1 | C1 | - And the following "users" exist: - | username | - | student1 | - | teacher1 | - And the following "course enrolments" exist: - | user | course | role | - | student1 | C1 | student | - | teacher1 | C1 | teacher | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | - And the following "question categories" exist: - | contextlevel | reference | name | - | Course | C1 | Test questions | - And the following "questions" exist: - | questioncategory | qtype | name | questiontext | - | Test questions | truefalse | TF1 | Text of the first question | - | Test questions | truefalse | TF2 | Text of the second question | - And quiz "Quiz 1" contains the following questions: - | question | page | - | TF1 | 1 | - | TF2 | 2 | - - @app_from3.7.1 - Scenario: Student attempt a quiz in app and teacher see the results. - Given I enter the app - And I log in as "student1" - When I press "Course 1" near "Course overview" in the app - And I press "Quiz 1" in the app - And I press "Attempt quiz now" in the app - Then I should see "Text of the first question" - And I should not see "Text of the second question" - And I press "True" in the app - And I press "Next" near "Question 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "False" in the app - And I press "Clear my choice" in the app - And I press "True" in the app - And I press "Next" in the app - And I press "Submit all and finish" in the app - And I should see "OK" - And I press "OK" in the app - And I should see "Review" - Given I enter the app - And I log in as "teacher1" - When I press "Course 1" near "Course overview" in the app - And I press "Quiz 1" in the app - And I press "Information" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "teacher1" - And I press "Actions menu" - And I follow "Results" - And I press "Download" - And I pause - And I close the browser tab opened by the app - \ No newline at end of file From 46cdf1daab3a8b28fe3eec0fa498a4cfa9e5bc8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 16 Dec 2019 12:03:41 +0100 Subject: [PATCH 023/220] MOBILE-3296 behat: Behat basic test for choice --- .../tests/behat/app_basic_usage.feature | 87 +++++++++++++++++-- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index dc3d45e7e..80e1086ae 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -9,8 +9,6 @@ Feature: Test basic usage in app | username | firstname | lastname | email | | teacher1 | Teacher | teacher | teacher1@example.com | | student1 | Student | student | student1@example.com | - | student2 | Student | 2 | student2@example.com | - | student3 | Student | 3 | student3@example.com | And the following "courses" exist: | fullname | shortname | category | | Course 1 | C1 | 0 | @@ -18,8 +16,6 @@ Feature: Test basic usage in app | user | course | role | | teacher1 | C1 | editingteacher | | student1 | C1 | student | - | student2 | C1 | student | - | student3 | C1 | student | And the following "activities" exist: | activity | name | intro | course | idnumber | option | | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | @@ -49,7 +45,7 @@ Feature: Test basic usage in app And I should see "Option 3: 0" @3.8.0 @OK - Scenario: Student sends, changes and remove their multi choice + Scenario: Student sends, changes and removes the multi choice Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | @@ -76,9 +72,87 @@ Feature: Test basic usage in app And I should not see "Remove my choice" And I should see "The results are not currently viewable" + @3.8.0 @OK + Scenario: Student answers, changes answer offline and sync + Given the following "activities" exist: + | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | + | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test single choice name" in the app + And I press "Option 1" in the app + And I switch offline mode to "true" + And I press "Option 2" in the app + And I press "Save my choice" in the app + And I should see "Are you sure" + And I press "OK" in the app + And I press "arrow back" in the app + And I press "Test single choice name" in the app + And I switch offline mode to "false" + And I press "arrow back" in the app + And I press "Test single choice name" in the app + Then I should see "Option 1: 0" + And I should see "Option 2: 1" + And I should see "Option 3: 0" + And I should not see "Remove my choice" @3.8.0 @OK - Scenario: Download student choice in text format + Scenario: Student answers, changes answer offline and auto-sync + Given the following "activities" exist: + | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | + | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test single choice name" in the app + And I press "Option 1" in the app + And I switch offline mode to "true" + And I press "Option 2" in the app + And I press "Save my choice" in the app + And I should see "Are you sure" + And I press "OK" in the app + And I switch offline mode to "false" + And I wait "600" seconds + Then I should see "Option 1: 0" + And I should see "Option 2: 1" + And I should see "Option 3: 0" + And I should not see "Remove my choice" + + @3.8.0 @OK + Scenario: Prefetch + Given the following "activities" exist: + | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | + | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Information" in the app + And I press "Show download options" in the app + And I press "cloud download" near "Test single choice name" in the app + And I switch offline mode to "true" + And I press "Choice name" in the app + And I should see "There was a problem connecting to the site. Please check your connection and try again." + And I press "OK" in the app + And I press "arrow back" in the app + And I press "Test single choice name" in the app + And I press "Option 1" in the app + And I press "Option 2" in the app + And I press "Save my choice" in the app + And I should see "Are you sure" + And I press "OK" in the app + And I press "arrow back" in the app + And I press "Test single choice name" in the app + And I switch offline mode to "false" + And I press "arrow back" in the app + And I press "Test single choice name" in the app + Then I should see "Option 1: 0" + And I should see "Option 2: 1" + And I should see "Option 3: 0" + And I should not see "Remove my choice" + + @3.8.0 @OK + Scenario: Download students choice in text format When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -100,4 +174,3 @@ Feature: Test basic usage in app And I follow "View 1 responses" And I press "Download in text format" And I close the browser tab opened by the app - From d571a9a32e2f9dd7ff016c1ae52c32315f9537bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Fri, 20 Dec 2019 18:27:54 +0100 Subject: [PATCH 024/220] MOBILE-3295 behat: Behat basic test for forum --- mod/forum/tests/behat/app_basic_usage.feature | 256 +++++++++++++++--- 1 file changed, 223 insertions(+), 33 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 02dd888bf..145ba3261 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -11,16 +11,18 @@ Feature: Test basic usage in app And the following "users" exist: | username | | student1 | + | student2 | | teacher1 | | teacher2 | And the following "course enrolments" exist: | user | course | role | | student1 | C1 | student | + | student2 | C1 | student | | teacher1 | C1 | editingteacher | | teacher2 | C1 | editingteacher | And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | - | forum | Test forum name | Test forum | C1 | forum | 0 | + | activity | name | intro | course | idnumber | groupmode | assessed | scale[modgrade_type] | + | forum | Test forum name | Test forum | C1 | forum | 0 | 5 | Point | Scenario: Student starts a discussion When I enter the app @@ -83,7 +85,7 @@ Feature: Test basic usage in app And I close the browser tab opened by the app And I press the back button in the app - @mobile @latest + @app @mobile @3.8.0 Scenario: Student star a discussion When I enter the app And I log in as "student1" @@ -115,7 +117,7 @@ Feature: Test basic usage in app And I pause - @mobile @latest + @app @mobile @3.8.0 Scenario: Teacher star and pin a discussion When I enter the app And I log in as "teacher1" @@ -161,7 +163,7 @@ Feature: Test basic usage in app And I should see "Auto-test pin" And I pause -@mobile @3.6 @OK + @app @mobile @3.6 @OK Scenario: Teacher checks pin and star in 3.6 When I enter the app And I log in as "teacher1" @@ -178,10 +180,10 @@ Feature: Test basic usage in app And I should not see "Pin this discussion" - @mobile + @app @mobile @3.8.0 Scenario: Edit a forum post (only online) When I enter the app - And I log in as "teacher1" + And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app And I press "close" in the app @@ -189,21 +191,21 @@ Feature: Test basic usage in app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app Then I should see "Auto-test" - And I should see "Auto-test message" - And I press "Auto-test" in the app - And I press "Auto-test message" in the app + And I press "arrow back" in the app And I press "Information" in the app + And I press "Show download options" in the app + And I press "cloud download" near "Test forum name" in the app + And I press "Test forum name" in the app + And I press "Auto-test" in the app + And I wait "2" seconds + And I pause + And I press "More" in the app + And I should see "Edit" + And I pause + And I switch offline mode to "true" And I pause - And I pause - And I press "Information" near "Test forum name" in the app - And I switch to the browser tab opened by the app - And I log in as "admin" - And I press "Actions menu" - And I follow "Edit settings" - And I press "Ratings" - - @mobile @latest + @app @mobile @3.8.0 Scenario: Add/view ratings When I enter the app And I log in as "student1" @@ -213,23 +215,211 @@ Feature: Test basic usage in app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app - And I pause - And I press "Information" near "Test forum name" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "admin" - And I press "Actions menu" - And I follow "Edit settings" - And I press "Ratings" - And I press "No ratings" - And I press "Average of ratings" - And I press "None" - And I press "Point" - And I press "Save and display" - And I pause + And I press "Auto-test" in the app + And I press "Reply" in the app + And I set the field "Write your reply..." to "test" in the app + And I press "Post to forum" in the app When I enter the app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app And I press "Auto-test" in the app And I pause + + @app @3.8.0 @mobile @OK + Scenario: Student replies a post offline mobile + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject" in the app + And I set the field "Message" to "DiscussionMessage" in the app + And I press "Post to forum" in the app + And I press "arrow back" in the app + And I press "Information" in the app + And I press "Show download options" in the app + And I press "cloud download" near "Test forum name" in the app + And I press "Test forum name" in the app + And I press "DiscussionSubject" in the app + And I switch offline mode to "true" + And I press "Reply" in the app + And I set the field "Write your reply" to "ReplyMessage" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionMessage" + And I should see "ReplyMessage" + And I should see "Not sent" + And I press "arrow back" in the app + And I switch offline mode to "false" + And I press "DiscussionSubject" in the app + Then I should see "DiscussionMessage" + And I should see "ReplyMessage" + And I should not see "Not sent" + + @app @3.8.0 @tablet @OK + Scenario: Student replies a post offline tablet + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject" in the app + And I set the field "Message" to "DiscussionMessage" in the app + And I press "Post to forum" in the app + And I press "arrow back" in the app + And I press "Information" in the app + And I press "Show download options" in the app + And I press "cloud download" near "Test forum name" in the app + And I press "Test forum name" in the app + And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app + And I switch offline mode to "true" + And I press "Reply" in the app + And I set the field "Write your reply" to "ReplyMessage" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionMessage" + And I should see "ReplyMessage" + And I should see "Not sent" + And I press "arrow back" in the app + And I switch offline mode to "false" + And I press "Test forum name" in the app + And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app + Then I should see "DiscussionMessage" + And I should see "ReplyMessage" + And I should not see "Not sent" + + @app @3.8.0 @OK + Scenario: Student creates a new discussion offline and sync forum + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I switch offline mode to "true" + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject" in the app + And I set the field "Message" to "DiscussionMessage" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionSubject" + And I should see "Not sent" + And I switch offline mode to "false" + And I press "arrow back" in the app + And I press "Test forum name" in the app + And I press "Information" in the app + And I press "Refresh discussions" in the app + And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app + Then I should see "DiscussionSubject" + And I should see "DiscussionMessage" + And I should not see "Not sent" + + @app @3.8.0 @OK + Scenario: Student creates a new discussion offline and auto-sync forum + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I switch offline mode to "true" + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject" in the app + And I set the field "Message" to "DiscussionMessage" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionSubject" + And I should see "Not sent" + And I switch offline mode to "false" + And I wait "600" seconds + And I should not see "Not sent" + And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app + Then I should see "DiscussionSubject" + And I should see "DiscussionMessage" + And I should not see "Not sent" + + @app @3.8.0 @mobile @OK + Scenario: Prefetch mobile + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject" in the app + And I set the field "Message" to "DiscussionMessage" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionSubject" + And I press "arrow back" in the app + And I press "Information" in the app + And I press "Show download options" in the app + And I press "cloud download" near "Test forum name" in the app + And I press "Test forum name" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject 2" in the app + And I set the field "Message" to "DiscussionMessage 2" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionSubject" + And I should see "DiscussionSubject 2" + And I press "arrow back" in the app + And I switch offline mode to "true" + And I press "Test forum name" in the app + And I press "DiscussionSubject 2" in the app + Then I should see "There was a problem connecting to the site. Please check your connection and try again." + And I press "OK" in the app + And I press "arrow back" in the app + And I press "DiscussionSubject" in the app + Then I should see "DiscussionSubject" + And I should see "DiscussionMessage" + And I should not see "There was a problem connecting to the site. Please check your connection and try again." + + + @app @3.8.0 @tablet + Scenario: Prefetch tablet + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject" in the app + And I set the field "Message" to "DiscussionMessage" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionSubject" + And I press "arrow back" in the app + And I press "Information" in the app + And I press "Show download options" in the app + And I press "cloud download" near "Test forum name" in the app + And I press "Test forum name" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject 2" in the app + And I set the field "Message" to "DiscussionMessage 2" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionSubject" + And I should see "DiscussionSubject 2" + And I press "arrow back" in the app + And I switch offline mode to "true" + And I press "Test forum name" in the app + And I pause + And I press "DiscussionSubject 2" in the app + Then I should see "There was a problem connecting to the site. Please check your connection and try again." + And I press "OK" in the app + And I press "DiscussionSubject" in the app + Then I should see "DiscussionSubject" + And I should see "DiscussionMessage" + + @app @3.8.0 + Scenario: Student sorts a forum discussion + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject" in the app + And I set the field "Message" to "DiscussionMessage" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionSubject" + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "DiscussionSubject more replies" in the app + And I set the field "Message" to "DiscussionMessage more replies" in the app + And I press "Post to forum" in the app + Then I should see "DiscussionSubject" + And I should see "DiscussionSubject more replies" + And I press "DiscussionSubject more replies" in the app + And I press "Reply" in the app + And I set the field "Write your reply" to "ReplyMessage" in the app + And I press "Post to forum" in the app + And I pause \ No newline at end of file From 57cddebb3eaeef2f9a8a1e707475e1288b0aed15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 2 Jan 2020 10:06:02 +0100 Subject: [PATCH 025/220] MOBILE-3295 MOBILE-3296 behat: Behat basic test for forum and choice --- mod/forum/tests/behat/app_basic_usage.feature | 25 +++--- .../tests/behat/app_basic_usage.feature | 78 ++++++++++++++++++- 2 files changed, 88 insertions(+), 15 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 145ba3261..56a1651eb 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -85,7 +85,7 @@ Feature: Test basic usage in app And I close the browser tab opened by the app And I press the back button in the app - @app @mobile @3.8.0 + @app @3.8.0 Scenario: Student star a discussion When I enter the app And I log in as "student1" @@ -117,7 +117,7 @@ Feature: Test basic usage in app And I pause - @app @mobile @3.8.0 + @app @3.8.0 Scenario: Teacher star and pin a discussion When I enter the app And I log in as "teacher1" @@ -163,7 +163,7 @@ Feature: Test basic usage in app And I should see "Auto-test pin" And I pause - @app @mobile @3.6 @OK + @app @3.6 @OK Scenario: Teacher checks pin and star in 3.6 When I enter the app And I log in as "teacher1" @@ -180,7 +180,7 @@ Feature: Test basic usage in app And I should not see "Pin this discussion" - @app @mobile @3.8.0 + @app @3.8.0 Scenario: Edit a forum post (only online) When I enter the app And I log in as "student1" @@ -199,13 +199,13 @@ Feature: Test basic usage in app And I press "Auto-test" in the app And I wait "2" seconds And I pause - And I press "More" in the app + And I press "" in the app And I should see "Edit" And I pause And I switch offline mode to "true" And I pause - @app @mobile @3.8.0 + @app @3.8.0 Scenario: Add/view ratings When I enter the app And I log in as "student1" @@ -367,7 +367,7 @@ Feature: Test basic usage in app And I should not see "There was a problem connecting to the site. Please check your connection and try again." - @app @3.8.0 @tablet + @app @3.8.0 @tablet @OK Scenario: Prefetch tablet When I enter the app And I change viewport size to "1280x1080" @@ -392,15 +392,18 @@ Feature: Test basic usage in app And I should see "DiscussionSubject 2" And I press "arrow back" in the app And I switch offline mode to "true" - And I press "Test forum name" in the app - And I pause - And I press "DiscussionSubject 2" in the app + And I press "refresh" near "Test forum name" in the app Then I should see "There was a problem connecting to the site. Please check your connection and try again." And I press "OK" in the app + And I press "Test forum name" in the app And I press "DiscussionSubject" in the app Then I should see "DiscussionSubject" And I should see "DiscussionMessage" - + And I press "arrow back" in the app + And I switch offline mode to "false" + And I press "refresh" near "Test forum name" in the app + Then I should not see "There was a problem connecting to the site. Please check your connection and try again." + @app @3.8.0 Scenario: Student sorts a forum discussion When I enter the app diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index 957c2fd09..390cafdde 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -20,8 +20,8 @@ Feature: Test basic usage in app | activity | name | intro | course | idnumber | groupmode | | survey | Test survey name | Test survey | C1 | survey | 0 | - @Mobile @3.8.0 @OK - Scenario: Student answer a survey and see results + @app @3.8.0 @mobile @OK + Scenario: Student answers a survey ATTLS and see results mobile When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -74,13 +74,83 @@ Feature: Test basic usage in app Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." And I should see "1 people have completed this survey so far" - @Tablet @3.8.0 - Scenario: Student answer a survey and see results tablet + @app @3.8.0 @tablet + Scenario: Student answer a survey ATTLS and see results tablet When I enter the app And I change viewport size to "1280x1080" And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test survey name" in the app And I pause + + @app @3.8.0 + Scenario: Student answers a survey of critical incidents and see results + Given the following "activities" exist: + | activity | name | intro | template |course | idnumber | groupmode | + | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey critical incidents" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "Results" + And I press "Results" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "Test survey critical incidents" + And I pause + + @app @3.8.0 @OK + Scenario: Sync survey + Given the following "activities" exist: + | activity | name | intro | template |course | idnumber | groupmode | + | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey critical incidents" in the app + And I switch offline mode to "true" + And I press "Submit" in the app + And I press "OK" in the app + And I switch offline mode to "false" + And I press "arrow back" in the app + And I press "Test survey critical incidents" in the app + And I press "Information" in the app + And I press "Refresh" in the app + Then I should see "Results" + + + @app @3.8.0 @OK + Scenario: Prefetch and auto-sync + Given the following "activities" exist: + | activity | name | intro | template |course | idnumber | groupmode | + | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Information" in the app + And I press "Show download options" in the app + And I press "cloud download" near "Test survey critical incidents" in the app + And I switch offline mode to "true" + And I press "Test survey name" in the app + Then I should see "There was a problem connecting to the site. Please check your connection and try again." + And I press "OK" in the app + And I press "arrow back" in the app + And I press "Test survey critical incidents" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "This Survey has offline data to be synchronised." + And I switch offline mode to "false" + And I wait "600" seconds + Then I should not see "This Survey has offline data to be synchronised." + And I should see "You have completed this survey." + + + @app @3.8.0 + Scenario: Student answers a survey offline + When I enter the app + And I log in as "student1" + And I pause From 6ae980be6a3179296db6873b26ef952ed967b02d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 8 Jan 2020 09:19:19 +0100 Subject: [PATCH 026/220] MOBILE-3297 behat: Behat basic test for survey finished --- .../tests/behat/app_basic_usage.feature | 474 +++++++++++++++++- 1 file changed, 457 insertions(+), 17 deletions(-) diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index 390cafdde..a2d3aae30 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -2,7 +2,7 @@ Feature: Test basic usage in app In order to participate in surveys while using the mobile app As a student - I need basic forum functionality to work + I need basic survey functionality to work Background: Given the following "courses" exist: @@ -74,16 +74,43 @@ Feature: Test basic usage in app Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." And I should see "1 people have completed this survey so far" - @app @3.8.0 @tablet - Scenario: Student answer a survey ATTLS and see results tablet + @app @3.8.0 @tablet @OK + Scenario: Student answers a survey ATTLS and see results tablet When I enter the app And I change viewport size to "1280x1080" And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test survey name" in the app - And I pause + And I press "1. In evaluating what someone says, I focus on the quality of their argument, not on the person who's presenting it." in the app + And I press "2. I like playing devil's advocate - arguing the opposite of what someone is saying." in the app + And I press "3. I like to understand where other people are 'coming from', what experiences have led them to feel the way they do." in the app + And I press "4. The most important part of my education has been learning to understand people who are very different to me." in the app + And I press "5. I feel that the best way for me to achieve my own identity is to interact with a variety of other people." in the app + And I press "6. I enjoy hearing the opinions of people who come from backgrounds different to mine - it helps me to understand how the same things can be seen in such different ways." in the app + And I press "7. I find that I can strengthen my own position through arguing with someone who disagrees with me." in the app + And I press "8. I am always interested in knowing why people say and believe the things they do." in the app + And I press "9. I often find myself arguing with the authors of books that I read, trying to logically figure out why they're wrong." in the app + And I press "10. It's important for me to remain as objective as possible when I analyze something." in the app + And I press "11. I try to think with people instead of against them." in the app + And I press "12. I have certain criteria I use in evaluating arguments." in the app + And I press "13. I'm more likely to try to understand someone else's opinion than to try to evaluate it." in the app + And I press "14. I try to point out weaknesses in other people's thinking to help them clarify their arguments." in the app + And I press "15. I tend to put myself in other people's shoes when discussing controversial issues, to see why they think the way they do." in the app + And I press "16. One could call my way of analysing things 'putting them on trial' because I am careful to consider all the evidence." in the app + And I press "17. I value the use of logic and reason over the incorporation of my own concerns when solving problems." in the app + And I press "18. I can obtain insight into opinions that differ from mine through empathy." in the app + And I press "19. When I encounter people whose opinions seem alien to me, I make a deliberate effort to 'extend' myself into that person, to try to see how they could have those opinions." in the app + And I press "20. I spend time figuring out what's 'wrong' with things. For example, I'll look for something in a literary interpretation that isn't argued well enough." in the app + And I press "Submit" in the app + And I press "OK" in the app + And I press "open" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" - @app @3.8.0 + + @app @3.8.0 @OK Scenario: Student answers a survey of critical incidents and see results Given the following "activities" exist: | activity | name | intro | template |course | idnumber | groupmode | @@ -99,10 +126,432 @@ Feature: Test basic usage in app And I switch to the browser tab opened by the app And I log in as "student1" Then I should see "Test survey critical incidents" - And I pause + + @app @3.8.0 @mobile @OK + Scenario: Student answers a survey of Colles (actual) and see results mobile + Given the following "activities" exist: + | activity | name | intro | template |course | idnumber | groupmode | + | survey | Test survey Colles (actual) | Test survey1 | 1 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey Colles (actual)" in the app + And I press "Choose" near "1. my learning focuses on issues that interest me." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "2. what I learn is important for my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "3. I learn how to improve my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "4. what I learn connects well with my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "5. I think critically about how I learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "6. I think critically about my own ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "7. I think critically about other students' ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "8. I think critically about ideas in the readings." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "9. I explain my ideas to other students." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "10. I ask other students to explain their ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "11. other students ask me to explain my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "12. other students respond to my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "13. the tutor stimulates my thinking." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "14. the tutor encourages me to participate." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "15. the tutor models good discourse." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "16. the tutor models critical self-reflection." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "17. other students encourage my participation." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "18. other students praise my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "19. other students value my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "20. other students empathise with my struggle to learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "21. I make good sense of other students' messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "22. other students make good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "23. I make good sense of the tutor's messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "24. the tutor makes good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "25. How long did this survey take you to complete?" in the app + And I press "under 1 min" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "You have completed this survey" + And I should see "Results" + And I press "Results" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" + + @app @3.8.0 @tablet @OK + Scenario: Student answers a survey of Colles (actual) and see results tablet + Given the following "activities" exist: + | activity | name | intro | template |course | idnumber | groupmode | + | survey | Test survey Colles (actual) | Test survey1 | 1 | C1 | survey1 | 0 | + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey Colles (actual)" in the app + And I press "1. my learning focuses on issues that interest me." in the app + And I press "2. what I learn is important for my professional practice." in the app + And I press "3. I learn how to improve my professional practice." in the app + And I press "4. what I learn connects well with my professional practice." in the app + And I press "5. I think critically about how I learn." in the app + And I press "6. I think critically about my own ideas." in the app + And I press "7. I think critically about other students' ideas." in the app + And I press "8. I think critically about ideas in the readings." in the app + And I press "9. I explain my ideas to other students." in the app + And I press "10. I ask other students to explain their ideas." in the app + And I press "11. other students ask me to explain my ideas." in the app + And I press "12. other students respond to my ideas." in the app + And I press "13. the tutor stimulates my thinking." in the app + And I press "14. the tutor encourages me to participate." in the app + And I press "15. the tutor models good discourse." in the app + And I press "16. the tutor models critical self-reflection." in the app + And I press "17. other students encourage my participation." in the app + And I press "18. other students praise my contribution." in the app + And I press "19. other students value my contribution." in the app + And I press "20. other students empathise with my struggle to learn." in the app + And I press "21. I make good sense of other students' messages." in the app + And I press "22. other students make good sense of my messages." in the app + And I press "23. I make good sense of the tutor's messages." in the app + And I press "24. the tutor makes good sense of my messages." in the app + And I press "25. How long did this survey take you to complete?" in the app + And I press "under 1 min" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "You have completed this survey" + And I should see "Results" + And I press "Results" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" + + + @app @3.8.0 @mobile @OK + Scenario: Student answers a survey of Colles (preferred) and see results mobile + Given the following "activities" exist: + | activity | name | intro | template |course | idnumber | groupmode | + | survey | Test survey Colles (preferred) | Test survey1 | 2 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey Colles (preferred)" in the app + And I press "Choose" near "1. my learning focuses on issues that interest me." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "2. what I learn is important for my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "3. I learn how to improve my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "4. what I learn connects well with my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "5. I think critically about how I learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "6. I think critically about my own ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "7. I think critically about other students' ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "8. I think critically about ideas in the readings." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "9. I explain my ideas to other students." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "10. I ask other students to explain their ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "11. other students ask me to explain my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "12. other students respond to my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "13. the tutor stimulates my thinking." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "14. the tutor encourages me to participate." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "15. the tutor models good discourse." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "16. the tutor models critical self-reflection." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "17. other students encourage my participation." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "18. other students praise my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "19. other students value my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "20. other students empathise with my struggle to learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "21. I make good sense of other students' messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "22. other students make good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "23. I make good sense of the tutor's messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "24. the tutor makes good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "25. How long did this survey take you to complete?" in the app + And I press "under 1 min" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "You have completed this survey" + And I should see "Results" + And I press "Results" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" + + + @app @3.8.0 @tablet @OK + Scenario: Student answers a survey of Colles (preferred) and see results tablet + Given the following "activities" exist: + | activity | name | intro | template |course | idnumber | groupmode | + | survey | Test survey Colles (preferred) | Test survey1 | 2 | C1 | survey1 | 0 | + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey Colles (preferred)" in the app + And I press "1. my learning focuses on issues that interest me." in the app + And I press "2. what I learn is important for my professional practice." in the app + And I press "3. I learn how to improve my professional practice." in the app + And I press "4. what I learn connects well with my professional practice." in the app + And I press "5. I think critically about how I learn." in the app + And I press "6. I think critically about my own ideas." in the app + And I press "7. I think critically about other students' ideas." in the app + And I press "8. I think critically about ideas in the readings." in the app + And I press "9. I explain my ideas to other students." in the app + And I press "10. I ask other students to explain their ideas." in the app + And I press "11. other students ask me to explain my ideas." in the app + And I press "12. other students respond to my ideas." in the app + And I press "13. the tutor stimulates my thinking." in the app + And I press "14. the tutor encourages me to participate." in the app + And I press "15. the tutor models good discourse." in the app + And I press "16. the tutor models critical self-reflection." in the app + And I press "17. other students encourage my participation." in the app + And I press "18. other students praise my contribution." in the app + And I press "19. other students value my contribution." in the app + And I press "20. other students empathise with my struggle to learn." in the app + And I press "21. I make good sense of other students' messages." in the app + And I press "22. other students make good sense of my messages." in the app + And I press "23. I make good sense of the tutor's messages." in the app + And I press "24. the tutor makes good sense of my messages." in the app + And I press "25. How long did this survey take you to complete?" in the app + And I press "under 1 min" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "You have completed this survey" + And I should see "Results" + And I press "Results" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" + + + + @app @3.8.0 @mobile @OK + Scenario: Student answers a survey of Colles (preferred and actual) and see results mobile + Given the following "activities" exist: + | activity | name | intro | template |course | idnumber | groupmode | + | survey | Test survey Colles (preferred and actual) | Test survey1 | 3 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey Colles (preferred and actual)" in the app + And I press "Choose" near "1. I prefer that my learning focuses on issues that interest me." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "2. I found that my learning focuses on issues that interest me." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "3. I prefer that what I learn is important for my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "4. I found that what I learn is important for my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "5. I prefer that I learn how to improve my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "6. I found that I learn how to improve my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "7. I prefer that what I learn connects well with my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "8. I found that what I learn connects well with my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "9. I prefer that I think critically about how I learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "10. I found that I think critically about how I learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "11. I prefer that I think critically about my own ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "12. I found that I think critically about my own ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "13. I prefer that I think critically about other students' ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "14. I found that I think critically about other students' ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "15. I prefer that I think critically about ideas in the readings." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "16. I found that I think critically about ideas in the readings." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "17. I prefer that I explain my ideas to other students." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "18. I found that I explain my ideas to other students." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "19. I prefer that I ask other students to explain their ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "20. I found that I ask other students to explain their ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "21. I prefer that other students ask me to explain my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "22. I found that other students ask me to explain my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "23. I prefer that other students respond to my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "24. I found that other students respond to my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "25. I prefer that the tutor stimulates my thinking." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "26. I found that the tutor stimulates my thinking." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "27. I prefer that the tutor encourages me to participate." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "28. I found that the tutor encourages me to participate." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "29. I prefer that the tutor models good discourse." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "30. I found that the tutor models good discourse." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "31. I prefer that the tutor models critical self-reflection." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "32. I found that the tutor models critical self-reflection." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "33. I prefer that other students encourage my participation." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "34. I found that other students encourage my participation." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "35. I prefer that other students praise my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "36. I found that other students praise my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "37. I prefer that other students value my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "38. I found that other students value my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "39. I prefer that other students empathise with my struggle to learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "40. I found that other students empathise with my struggle to learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "41. I prefer that I make good sense of other students' messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "42. I found that I make good sense of other students' messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "43. I prefer that other students make good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "44. I found that other students make good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "45. I prefer that I make good sense of the tutor's messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "46. I found that I make good sense of the tutor's messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "47. I prefer that the tutor makes good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "48. I found that the tutor makes good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "49. How long did this survey take you to complete?" in the app + And I press "1-2 min" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "You have completed this survey" + And I should see "Results" + And I press "Results" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" + + + @app @3.8.0 @tablet @OK + Scenario: Student answers a survey of Colles (preferred and actual) and see results tablet + Given the following "activities" exist: + | activity | name | intro | template |course | idnumber | groupmode | + | survey | Test survey Colles (preferred and actual) | Test survey1 | 3 | C1 | survey1 | 0 | + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey Colles (preferred and actual)" in the app + And I press "1. I prefer that my learning focuses on issues that interest me." in the app + And I press "2. I found that my learning focuses on issues that interest me." in the app + And I press "3. I prefer that what I learn is important for my professional practice." in the app + And I press "4. I found that what I learn is important for my professional practice." in the app + And I press "5. I prefer that I learn how to improve my professional practice." in the app + And I press "6. I found that I learn how to improve my professional practice." in the app + And I press "7. I prefer that what I learn connects well with my professional practice." in the app + And I press "8. I found that what I learn connects well with my professional practice." in the app + And I press "9. I prefer that I think critically about how I learn." in the app + And I press "10. I found that I think critically about how I learn." in the app + And I press "11. I prefer that I think critically about my own ideas." in the app + And I press "12. I found that I think critically about my own ideas." in the app + And I press "13. I prefer that I think critically about other students' ideas." in the app + And I press "14. I found that I think critically about other students' ideas." in the app + And I press "15. I prefer that I think critically about ideas in the readings." in the app + And I press "16. I found that I think critically about ideas in the readings." in the app + And I press "17. I prefer that I explain my ideas to other students." in the app + And I press "18. I found that I explain my ideas to other students." in the app + And I press "19. I prefer that I ask other students to explain their ideas." in the app + And I press "20. I found that I ask other students to explain their ideas." in the app + And I press "21. I prefer that other students ask me to explain my ideas." in the app + And I press "22. I found that other students ask me to explain my ideas." in the app + And I press "23. I prefer that other students respond to my ideas." in the app + And I press "24. I found that other students respond to my ideas." in the app + And I press "25. I prefer that the tutor stimulates my thinking." in the app + And I press "26. I found that the tutor stimulates my thinking." in the app + And I press "27. I prefer that the tutor encourages me to participate." in the app + And I press "28. I found that the tutor encourages me to participate." in the app + And I press "29. I prefer that the tutor models good discourse." in the app + And I press "30. I found that the tutor models good discourse." in the app + And I press "31. I prefer that the tutor models critical self-reflection." in the app + And I press "32. I found that the tutor models critical self-reflection." in the app + And I press "33. I prefer that other students encourage my participation." in the app + And I press "34. I found that other students encourage my participation." in the app + And I press "35. I prefer that other students praise my contribution." in the app + And I press "36. I found that other students praise my contribution." in the app + And I press "37. I prefer that other students value my contribution." in the app + And I press "38. I found that other students value my contribution." in the app + And I press "39. I prefer that other students empathise with my struggle to learn." in the app + And I press "40. I found that other students empathise with my struggle to learn." in the app + And I press "41. I prefer that I make good sense of other students' messages." in the app + And I press "42. I found that I make good sense of other students' messages." in the app + And I press "43. I prefer that other students make good sense of my messages." in the app + And I press "44. I found that other students make good sense of my messages." in the app + And I press "45. I prefer that I make good sense of the tutor's messages." in the app + And I press "46. I found that I make good sense of the tutor's messages." in the app + And I press "47. I prefer that the tutor makes good sense of my messages." in the app + And I press "48. I found that the tutor makes good sense of my messages." in the app + And I press "49. How long did this survey take you to complete?" in the app + And I press "1-2 min" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "You have completed this survey" + And I should see "Results" + And I press "Results" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" + @app @3.8.0 @OK - Scenario: Sync survey + Scenario: Student answers a survey offline and sync survey Given the following "activities" exist: | activity | name | intro | template |course | idnumber | groupmode | | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | @@ -144,13 +593,4 @@ Feature: Test basic usage in app And I switch offline mode to "false" And I wait "600" seconds Then I should not see "This Survey has offline data to be synchronised." - And I should see "You have completed this survey." - - - @app @3.8.0 - Scenario: Student answers a survey offline - When I enter the app - And I log in as "student1" - And I pause - - + And I should see "You have completed this survey." \ No newline at end of file From 78619e16896fc7de81bb1c59dc6b54869e30271a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 9 Jan 2020 12:03:12 +0100 Subject: [PATCH 027/220] MOBILE-3295 MOBILE-3296 MOBILE-3297 behat: Improvements on forum, survey and choice --- .../tests/behat/app_basic_usage.feature | 36 +++++++++++++------ mod/forum/tests/behat/app_basic_usage.feature | 27 +++++++++----- .../tests/behat/app_basic_usage.feature | 6 ++-- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 80e1086ae..5b703e00f 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -1,5 +1,5 @@ @mod @mod_choice @app @javascript -Feature: Test basic usage in app +Feature: Test basic usage of choice activity in app In order to participate in the choice while using the mobile app As a student I need basic choice functionality to work @@ -20,7 +20,7 @@ Feature: Test basic usage in app | activity | name | intro | course | idnumber | option | | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | - @3.8.0 @OK + @app @3.8.0 @OK Scenario: Student sends their single choice and views results. Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | @@ -44,7 +44,7 @@ Feature: Test basic usage in app And I should see "Option 2: 1" And I should see "Option 3: 0" - @3.8.0 @OK + @app @3.8.0 @OK Scenario: Student sends, changes and removes the multi choice Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | @@ -72,7 +72,7 @@ Feature: Test basic usage in app And I should not see "Remove my choice" And I should see "The results are not currently viewable" - @3.8.0 @OK + @app @3.8.0 @OK Scenario: Student answers, changes answer offline and sync Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | @@ -85,19 +85,25 @@ Feature: Test basic usage in app And I switch offline mode to "true" And I press "Option 2" in the app And I press "Save my choice" in the app - And I should see "Are you sure" + Then I should see "Are you sure" And I press "OK" in the app And I press "arrow back" in the app And I press "Test single choice name" in the app + Then I should not see "Option 1: 0" + And I should not see "Option 2: 1" + And I should not see "Option 3: 0" + And I should see "This Choice has offline data to be synchronised." And I switch offline mode to "false" And I press "arrow back" in the app And I press "Test single choice name" in the app + And I press "Information" in the app + And I press "Refresh" in the app Then I should see "Option 1: 0" And I should see "Option 2: 1" And I should see "Option 3: 0" - And I should not see "Remove my choice" + And I should not see "This Choice has offline data to be synchronised." - @3.8.0 @OK + @app @3.8.0 @OK Scenario: Student answers, changes answer offline and auto-sync Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | @@ -113,13 +119,17 @@ Feature: Test basic usage in app And I should see "Are you sure" And I press "OK" in the app And I switch offline mode to "false" + Then I should not see "Option 1: 0" + And I should not see "Option 2: 1" + And I should not see "Option 3: 0" + And I should see "This Choice has offline data to be synchronised." And I wait "600" seconds Then I should see "Option 1: 0" And I should see "Option 2: 1" And I should see "Option 3: 0" - And I should not see "Remove my choice" + And I should not see "This Choice has offline data to be synchronised." - @3.8.0 @OK + @app @3.8.0 @OK Scenario: Prefetch Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | @@ -143,15 +153,19 @@ Feature: Test basic usage in app And I press "OK" in the app And I press "arrow back" in the app And I press "Test single choice name" in the app + And I should not see "Option 1: 0" + And I should not see "Option 2: 1" + And I should not see "Option 3: 0" + And I should see "This Choice has offline data to be synchronised." And I switch offline mode to "false" And I press "arrow back" in the app And I press "Test single choice name" in the app Then I should see "Option 1: 0" And I should see "Option 2: 1" And I should see "Option 3: 0" - And I should not see "Remove my choice" + And I should not see "This Choice has offline data to be synchronised." - @3.8.0 @OK + @app @3.8.0 @OK Scenario: Download students choice in text format When I enter the app And I log in as "student1" diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 56a1651eb..d37a232f2 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -1,5 +1,5 @@ @mod @mod_forum @app @javascript -Feature: Test basic usage in app +Feature: Test basic usage of forum activity in app In order to participate in the forum while using the mobile app As a student I need basic forum functionality to work @@ -24,6 +24,7 @@ Feature: Test basic usage in app | activity | name | intro | course | idnumber | groupmode | assessed | scale[modgrade_type] | | forum | Test forum name | Test forum | C1 | forum | 0 | 5 | Point | + @app @3.8.0 @OK Scenario: Student starts a discussion When I enter the app And I log in as "student1" @@ -34,8 +35,10 @@ Feature: Test basic usage in app And I set the field "Message" to "An awesome message" in the app And I press "Post to forum" in the app Then I should see "My happy subject" + And I press "My happy subject" in the app And I should see "An awesome message" + @app_upto3.6.1 Scenario: Student posts a reply When I enter the app @@ -70,6 +73,7 @@ Feature: Test basic usage in app Then I should see "DiscussionMessage" And I should see "ReplyMessage" + @OK Scenario: Test that 'open in browser' works for forum When I enter the app And I change viewport size to "360x640" @@ -85,7 +89,7 @@ Feature: Test basic usage in app And I close the browser tab opened by the app And I press the back button in the app - @app @3.8.0 + @app @mobile @3.8.0 Scenario: Student star a discussion When I enter the app And I log in as "student1" @@ -104,7 +108,7 @@ Feature: Test basic usage in app And I press "Information" in the app And I press "Star this discussion" in the app And I press "arrow back" in the app - And I should see "Auto-test star" + Then I should see "Auto-test star" And I should see "Auto-test" And I pause And I press "Auto-test star" in the app @@ -117,7 +121,7 @@ Feature: Test basic usage in app And I pause - @app @3.8.0 + @app @mobile @3.8.0 Scenario: Teacher star and pin a discussion When I enter the app And I log in as "teacher1" @@ -163,7 +167,7 @@ Feature: Test basic usage in app And I should see "Auto-test pin" And I pause - @app @3.6 @OK + @app @mobile @3.6 @OK Scenario: Teacher checks pin and star in 3.6 When I enter the app And I log in as "teacher1" @@ -180,7 +184,7 @@ Feature: Test basic usage in app And I should not see "Pin this discussion" - @app @3.8.0 + @app @mobile @3.8.0 Scenario: Edit a forum post (only online) When I enter the app And I log in as "student1" @@ -199,13 +203,14 @@ Feature: Test basic usage in app And I press "Auto-test" in the app And I wait "2" seconds And I pause - And I press "" in the app + And I press "Auto-test" near "Information" in the app + And I pause And I should see "Edit" And I pause And I switch offline mode to "true" And I pause - @app @3.8.0 + @app @mobile @3.8.0 Scenario: Add/view ratings When I enter the app And I log in as "student1" @@ -220,7 +225,7 @@ Feature: Test basic usage in app And I set the field "Write your reply..." to "test" in the app And I press "Post to forum" in the app When I enter the app - And I log in as "teacher1" + And I log in as "student2" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app And I press "Auto-test" in the app @@ -301,6 +306,7 @@ Feature: Test basic usage in app And I press "Post to forum" in the app Then I should see "DiscussionSubject" And I should see "Not sent" + And I should see "This Forum has offline data to be synchronised." And I switch offline mode to "false" And I press "arrow back" in the app And I press "Test forum name" in the app @@ -310,6 +316,7 @@ Feature: Test basic usage in app Then I should see "DiscussionSubject" And I should see "DiscussionMessage" And I should not see "Not sent" + And I should not see "This Forum has offline data to be synchronised." @app @3.8.0 @OK Scenario: Student creates a new discussion offline and auto-sync forum @@ -324,6 +331,7 @@ Feature: Test basic usage in app And I press "Post to forum" in the app Then I should see "DiscussionSubject" And I should see "Not sent" + And I should see "This Forum has offline data to be synchronised." And I switch offline mode to "false" And I wait "600" seconds And I should not see "Not sent" @@ -331,6 +339,7 @@ Feature: Test basic usage in app Then I should see "DiscussionSubject" And I should see "DiscussionMessage" And I should not see "Not sent" + And I should not see "This Forum has offline data to be synchronised." @app @3.8.0 @mobile @OK Scenario: Prefetch mobile diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index a2d3aae30..90ad4668a 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -1,5 +1,5 @@ @mod @mod_survey @app @javascript -Feature: Test basic usage in app +Feature: Test basic usage of survey activity in app In order to participate in surveys while using the mobile app As a student I need basic survey functionality to work @@ -562,13 +562,15 @@ Feature: Test basic usage in app And I switch offline mode to "true" And I press "Submit" in the app And I press "OK" in the app + Then I should see "This Survey has offline data to be synchronised." And I switch offline mode to "false" And I press "arrow back" in the app And I press "Test survey critical incidents" in the app And I press "Information" in the app And I press "Refresh" in the app Then I should see "Results" - + And I should not see "This Survey has offline data to be synchronised." + And I should see "You have completed this survey." @app @3.8.0 @OK Scenario: Prefetch and auto-sync From 65581ad89cb84b12f8af80abad5df8bed27bf1bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 15 Jan 2020 11:30:51 +0100 Subject: [PATCH 028/220] MOBILE-3295 MOBILE-3296 MOBILE-3297 behat: Improvements on forum, survey and choice --- .../tests/behat/app_basic_usage.feature | 12 ++-- mod/forum/tests/behat/app_basic_usage.feature | 70 ++++++++++--------- .../tests/behat/app_basic_usage.feature | 5 +- 3 files changed, 46 insertions(+), 41 deletions(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 5b703e00f..5167bd33a 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -38,7 +38,7 @@ Feature: Test basic usage of choice activity in app And I should see "Option 2: 1" And I should see "Option 3: 0" And I should not see "Remove my choice" - And I press "arrow back" in the app + And I press the back button in the app And I press "Test single choice name" in the app And I should see "Option 1: 0" And I should see "Option 2: 1" @@ -87,14 +87,14 @@ Feature: Test basic usage of choice activity in app And I press "Save my choice" in the app Then I should see "Are you sure" And I press "OK" in the app - And I press "arrow back" in the app + And I press the back button in the app And I press "Test single choice name" in the app Then I should not see "Option 1: 0" And I should not see "Option 2: 1" And I should not see "Option 3: 0" And I should see "This Choice has offline data to be synchronised." And I switch offline mode to "false" - And I press "arrow back" in the app + And I press the back button in the app And I press "Test single choice name" in the app And I press "Information" in the app And I press "Refresh" in the app @@ -144,21 +144,21 @@ Feature: Test basic usage of choice activity in app And I press "Choice name" in the app And I should see "There was a problem connecting to the site. Please check your connection and try again." And I press "OK" in the app - And I press "arrow back" in the app + And I press the back button in the app And I press "Test single choice name" in the app And I press "Option 1" in the app And I press "Option 2" in the app And I press "Save my choice" in the app And I should see "Are you sure" And I press "OK" in the app - And I press "arrow back" in the app + And I press the back button in the app And I press "Test single choice name" in the app And I should not see "Option 1: 0" And I should not see "Option 2: 1" And I should not see "Option 3: 0" And I should see "This Choice has offline data to be synchronised." And I switch offline mode to "false" - And I press "arrow back" in the app + And I press the back button in the app And I press "Test single choice name" in the app Then I should see "Option 1: 0" And I should see "Option 2: 1" diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index d37a232f2..48cea02da 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -73,7 +73,6 @@ Feature: Test basic usage of forum activity in app Then I should see "DiscussionMessage" And I should see "ReplyMessage" - @OK Scenario: Test that 'open in browser' works for forum When I enter the app And I change viewport size to "360x640" @@ -90,7 +89,7 @@ Feature: Test basic usage of forum activity in app And I press the back button in the app @app @mobile @3.8.0 - Scenario: Student star a discussion + Scenario: Student stars a discussion When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -99,27 +98,32 @@ Feature: Test basic usage of forum activity in app And I set the field "Subject" to "Auto-test star" in the app And I set the field "Message" to "Auto-test star message" in the app And I press "Post to forum" in the app + And I wait "60" seconds And I press "close" in the app - And I set the field "Subject" to "Auto-test" in the app - And I set the field "Message" to "Auto-test message" in the app + And I set the field "Subject" to "Auto-test star" in the app + And I set the field "Message" to "Auto-test no star message" in the app And I press "Post to forum" in the app - And I press "Auto-test star" in the app - And I wait "1" seconds + And I press "Auto-test star" near "Last post a minute ago" in the app + Then I should see "Auto-test star message" And I press "Information" in the app And I press "Star this discussion" in the app - And I press "arrow back" in the app - Then I should see "Auto-test star" - And I should see "Auto-test" - And I pause - And I press "Auto-test star" in the app + And I press the back button in the app + And I press "Auto-test star" near "Last post a minute ago" in the app + Then I should see "Auto-test star message" + And I press the back button in the app + And I press "Auto-test star" near "Last post a few seconds ago" in the app + Then I should see "Auto-test no star message" + And I press the back button in the app + And I press "Auto-test star" near "Last post a minute ago" in the app And I wait "1" seconds And I press "Information" in the app And I press "Unstar this discussion" in the app - And I press "arrow back" in the app - Then I should see "Auto-test star" - And I should see "Auto-test" - And I pause - + And I press the back button in the app + And I press "Auto-test star" near "Last post a few seconds ago" in the app + Then I should see "Auto-test no star message" + And I press the back button in the app + And I press "Auto-test star" near "Last post a minute ago" in the app + Then I should see "Auto-test star message" @app @mobile @3.8.0 Scenario: Teacher star and pin a discussion @@ -143,12 +147,12 @@ Feature: Test basic usage of forum activity in app And I wait "1" seconds And I press "Information" in the app And I press "Star this discussion" in the app - And I press "arrow back" in the app + And I press the back button in the app And I press "Auto-test pin" in the app And I wait "1" seconds And I press "Information" in the app And I press "Pin this discussion" in the app - And I press "arrow back" in the app + And I press the back button in the app And I should see "Auto-test pin" And I should see "Auto-test star" And I should see "Auto-test" @@ -157,12 +161,12 @@ Feature: Test basic usage of forum activity in app And I wait "1" seconds And I press "Information" in the app And I press "Unpin this discussion" in the app - And I press "arrow back" in the app + And I press the back button in the app And I press "Auto-test star" in the app And I wait "1" seconds And I press "Information" in the app And I press "Unstar this discussion" in the app - And I press "arrow back" in the app + And I press the back button in the app Then I should see "Auto-test star" And I should see "Auto-test pin" And I pause @@ -195,7 +199,7 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app Then I should see "Auto-test" - And I press "arrow back" in the app + And I press the back button in the app And I press "Information" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app @@ -241,7 +245,7 @@ Feature: Test basic usage of forum activity in app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app - And I press "arrow back" in the app + And I press the back button in the app And I press "Information" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app @@ -254,7 +258,7 @@ Feature: Test basic usage of forum activity in app Then I should see "DiscussionMessage" And I should see "ReplyMessage" And I should see "Not sent" - And I press "arrow back" in the app + And I press the back button in the app And I switch offline mode to "false" And I press "DiscussionSubject" in the app Then I should see "DiscussionMessage" @@ -262,7 +266,7 @@ Feature: Test basic usage of forum activity in app And I should not see "Not sent" @app @3.8.0 @tablet @OK - Scenario: Student replies a post offline tablet + Scenario: Student replies a post offline tablet When I enter the app And I change viewport size to "1280x1080" And I log in as "student1" @@ -272,7 +276,7 @@ Feature: Test basic usage of forum activity in app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app - And I press "arrow back" in the app + And I press the back button in the app And I press "Information" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app @@ -285,7 +289,7 @@ Feature: Test basic usage of forum activity in app Then I should see "DiscussionMessage" And I should see "ReplyMessage" And I should see "Not sent" - And I press "arrow back" in the app + And I press the back button in the app And I switch offline mode to "false" And I press "Test forum name" in the app And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app @@ -308,7 +312,7 @@ Feature: Test basic usage of forum activity in app And I should see "Not sent" And I should see "This Forum has offline data to be synchronised." And I switch offline mode to "false" - And I press "arrow back" in the app + And I press the back button in the app And I press "Test forum name" in the app And I press "Information" in the app And I press "Refresh discussions" in the app @@ -352,7 +356,7 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app Then I should see "DiscussionSubject" - And I press "arrow back" in the app + And I press the back button in the app And I press "Information" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app @@ -363,13 +367,13 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app Then I should see "DiscussionSubject" And I should see "DiscussionSubject 2" - And I press "arrow back" in the app + And I press the back button in the app And I switch offline mode to "true" And I press "Test forum name" in the app And I press "DiscussionSubject 2" in the app Then I should see "There was a problem connecting to the site. Please check your connection and try again." And I press "OK" in the app - And I press "arrow back" in the app + And I press the back button in the app And I press "DiscussionSubject" in the app Then I should see "DiscussionSubject" And I should see "DiscussionMessage" @@ -388,7 +392,7 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app Then I should see "DiscussionSubject" - And I press "arrow back" in the app + And I press the back button in the app And I press "Information" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app @@ -399,7 +403,7 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app Then I should see "DiscussionSubject" And I should see "DiscussionSubject 2" - And I press "arrow back" in the app + And I press the back button in the app And I switch offline mode to "true" And I press "refresh" near "Test forum name" in the app Then I should see "There was a problem connecting to the site. Please check your connection and try again." @@ -408,7 +412,7 @@ Feature: Test basic usage of forum activity in app And I press "DiscussionSubject" in the app Then I should see "DiscussionSubject" And I should see "DiscussionMessage" - And I press "arrow back" in the app + And I press the back button in the app And I switch offline mode to "false" And I press "refresh" near "Test forum name" in the app Then I should not see "There was a problem connecting to the site. Please check your connection and try again." diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index 90ad4668a..08fa78a6c 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -252,6 +252,7 @@ Feature: Test basic usage of survey activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test survey Colles (preferred)" in the app + And I pause And I press "Choose" near "1. my learning focuses on issues that interest me." in the app And I press "Sometimes" near "Often" in the app And I press "Choose" near "2. what I learn is important for my professional practice." in the app @@ -564,7 +565,7 @@ Feature: Test basic usage of survey activity in app And I press "OK" in the app Then I should see "This Survey has offline data to be synchronised." And I switch offline mode to "false" - And I press "arrow back" in the app + And I press the back button in the app And I press "Test survey critical incidents" in the app And I press "Information" in the app And I press "Refresh" in the app @@ -587,7 +588,7 @@ Feature: Test basic usage of survey activity in app And I press "Test survey name" in the app Then I should see "There was a problem connecting to the site. Please check your connection and try again." And I press "OK" in the app - And I press "arrow back" in the app + And I press the back button in the app And I press "Test survey critical incidents" in the app And I press "Submit" in the app And I press "OK" in the app From 62850ca2d9551ac6ccb804e8af68eb1f64a14e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 16 Jan 2020 11:56:45 +0100 Subject: [PATCH 029/220] MOBILE-3300 behat: Behat basic test for courses --- .../tests/behat/app_basic_usage.feature | 2 +- .../tests/behat/app_basic_usage.feature | 97 +++++++++++++++++++ mod/forum/tests/behat/app_basic_usage.feature | 3 +- .../tests/behat/app_basic_usage.feature | 11 ++- 4 files changed, 110 insertions(+), 3 deletions(-) create mode 100755 mod/courses/tests/behat/app_basic_usage.feature diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 5167bd33a..24ee2e68c 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -187,4 +187,4 @@ Feature: Test basic usage of choice activity in app And I press "Actions menu" And I follow "View 1 responses" And I press "Download in text format" - And I close the browser tab opened by the app + And I close the browser tab opened by the app \ No newline at end of file diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature new file mode 100755 index 000000000..168441bdf --- /dev/null +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -0,0 +1,97 @@ +@mod @mod_courses @app @javascript +Feature: Test basic usage of courses in app + In order to participate in the courses while using the mobile app + As a student + I need basic courses functionality to work + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student | student | student1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + | Course 2 | C2 | 0 | + | Course 3 | C3 | 0 | + | Course 4 | C4 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | teacher1 | C2 | editingteacher | + | teacher1 | C3 | editingteacher | + | teacher1 | C4 | editingteacher | + | student1 | C1 | student | + | student1 | C2 | student | + | student1 | C3 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | option | + | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 2 | Test choice description | C2 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 3 | Test choice description | C3 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 4 | Test choice description | C4 | choice1 | Option 1, Option 2, Option 3 | + + @app @3.8.0 @OK + Scenario: Dashboard tab displayed in >= 3.3 sites + When I enter the app + And I log in as "student1" + Then I should see "Dashboard" + And the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" + And I press "Site home" in the app + Then I should see "Dashboard" + And the header should be "Acceptance test site" in the app + And I press "Dashboard" in the app + Then I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" + + @app @3.8.0 @OK + Scenario: See my courses + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" + And I press "Course 1" near "Recently accessed courses" in the app + Then I should see "Choice course 1" + And the header should be "Course 1" in the app + And I press "Choice course 1" in the app + Then I should see "Test choice description" + And the header should be "Choice course 1" in the app + And I press the back button in the app + And I press the back button in the app + And I press "Course 2" near "Recently accessed courses" in the app + Then I should see "Choice course 2" + And the header should be "Course 2" in the app + And I press the back button in the app + And I press "Course 3" near "Recently accessed courses" in the app + Then I should see "Choice course 3" + And the header should be "Course 3" in the app + + @app @3.8.0 + Scenario: Search for a course + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" + And I press "Search courses" in the app + And I set the field "Search" to "Course 4" in the app + And I press "Search" in the app + Then I should see "Course 4" + And the header should be "Search courses" in the app + And I press "Course 4" in the app + Then I should see "Course 4" + And the header should be "Course 4" in the app + And I press the back button in the app + And I set the field "Search" to "Course" in the app + And I press "Search" in the app + Then I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" + And I should see "Course 4" diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 48cea02da..9ce95940c 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -438,4 +438,5 @@ Feature: Test basic usage of forum activity in app And I press "Reply" in the app And I set the field "Write your reply" to "ReplyMessage" in the app And I press "Post to forum" in the app - And I pause \ No newline at end of file + And I pause + diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index 08fa78a6c..f184432dc 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -596,4 +596,13 @@ Feature: Test basic usage of survey activity in app And I switch offline mode to "false" And I wait "600" seconds Then I should not see "This Survey has offline data to be synchronised." - And I should see "You have completed this survey." \ No newline at end of file + And I should see "You have completed this survey." + + + + + + + + + From bad325e1c5f99a12df2f6efb6117c4de50111019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 16 Jan 2020 12:07:53 +0100 Subject: [PATCH 030/220] MOBILE-3295 MOBILE-3296 MOBILE-3297 MOBILE-3300 behat: Improvements on forum, survey, choice and courses --- mod/courses/tests/behat/app_basic_usage.feature | 2 +- mod/forum/tests/behat/app_basic_usage.feature | 3 +-- mod/survey/tests/behat/app_basic_usage.feature | 11 +---------- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index 168441bdf..8b62c266f 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -94,4 +94,4 @@ Feature: Test basic usage of courses in app Then I should see "Course 1" And I should see "Course 2" And I should see "Course 3" - And I should see "Course 4" + And I should see "Course 4" \ No newline at end of file diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 9ce95940c..48cea02da 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -438,5 +438,4 @@ Feature: Test basic usage of forum activity in app And I press "Reply" in the app And I set the field "Write your reply" to "ReplyMessage" in the app And I press "Post to forum" in the app - And I pause - + And I pause \ No newline at end of file diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index f184432dc..08fa78a6c 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -596,13 +596,4 @@ Feature: Test basic usage of survey activity in app And I switch offline mode to "false" And I wait "600" seconds Then I should not see "This Survey has offline data to be synchronised." - And I should see "You have completed this survey." - - - - - - - - - + And I should see "You have completed this survey." \ No newline at end of file From f56fd4a943d638dd1f00a14742b2ffee460ab896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Fri, 17 Jan 2020 15:30:23 +0100 Subject: [PATCH 031/220] MDL-67727 behat: Reset ionic app properly --- behat_app.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/behat_app.php b/behat_app.php index aebbed109..4996b2797 100644 --- a/behat_app.php +++ b/behat_app.php @@ -85,6 +85,10 @@ class behat_app extends behat_base { $this->getSession()->restart(); $this->resize_window('360x720', true); + if (empty($this->ionicurl)) { + $this->ionicurl = $this->start_or_reuse_ionic(); + } + // Go to page and prepare browser for app. $this->prepare_browser($this->ionicurl); } @@ -241,6 +245,7 @@ class behat_app extends behat_base { // the process. self::$ionicrunning = (object)['url' => $url, 'process' => $process, 'pipes' => $pipes, 'pid' => $pid]; + $url = self::$ionicrunning->url; } return $url; } From 47a9180a11a9d8f8ff6ddceba88a4e53700162ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Tue, 21 Jan 2020 10:03:59 +0100 Subject: [PATCH 032/220] MOBILE-3300 behat: Behat basic tests for courses --- .../tests/behat/app_basic_usage.feature | 79 +++++++++- mod/data/tests/behat/app_data_entries.feature | 46 ------ mod/data/tests/behat/app_data_sync.feature | 136 ------------------ .../tests/behat/app_quiz_navigation.feature | 110 -------------- 4 files changed, 72 insertions(+), 299 deletions(-) delete mode 100755 mod/data/tests/behat/app_data_entries.feature delete mode 100755 mod/data/tests/behat/app_data_sync.feature delete mode 100755 mod/quiz/tests/behat/app_quiz_navigation.feature diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index 8b62c266f..a22581dec 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -9,12 +9,14 @@ Feature: Test basic usage of courses in app | username | firstname | lastname | email | | teacher1 | Teacher | teacher | teacher1@example.com | | student1 | Student | student | student1@example.com | + And the following "courses" exist: | fullname | shortname | category | | Course 1 | C1 | 0 | | Course 2 | C2 | 0 | | Course 3 | C3 | 0 | | Course 4 | C4 | 0 | + And the following "course enrolments" exist: | user | course | role | | teacher1 | C1 | editingteacher | @@ -24,12 +26,17 @@ Feature: Test basic usage of courses in app | student1 | C1 | student | | student1 | C2 | student | | student1 | C3 | student | + And the following "activities" exist: - | activity | name | intro | course | idnumber | option | - | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | - | choice | Choice course 2 | Test choice description | C2 | choice1 | Option 1, Option 2, Option 3 | - | choice | Choice course 3 | Test choice description | C3 | choice1 | Option 1, Option 2, Option 3 | - | choice | Choice course 4 | Test choice description | C4 | choice1 | Option 1, Option 2, Option 3 | + | activity | name | intro | course | idnumber | option | + | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 2 | Test choice description | C2 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 3 | Test choice description | C3 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 4 | Test choice description | C4 | choice1 | Option 1, Option 2, Option 3 | + + And the following "activities" exist: + | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | + | assign | C1 | assign1 | assignment | Test assignment description | 1 | @app @3.8.0 @OK Scenario: Dashboard tab displayed in >= 3.3 sites @@ -72,7 +79,7 @@ Feature: Test basic usage of courses in app Then I should see "Choice course 3" And the header should be "Course 3" in the app - @app @3.8.0 + @app @3.8.0 @OK Scenario: Search for a course When I enter the app And I log in as "student1" @@ -94,4 +101,62 @@ Feature: Test basic usage of courses in app Then I should see "Course 1" And I should see "Course 2" And I should see "Course 3" - And I should see "Course 4" \ No newline at end of file + And I should see "Course 4" + + @app @3.8.0 @OK + Scenario: Links to actions in Timeline work for teachers/students + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" + And I should see "Timeline" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "assignment" in the app + And I press "Information" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "Edit settings" + And I press "Expand all" + And I click on "duedate[enabled]" "checkbox" + And I click on "gradingduedate[enabled]" "checkbox" + And I press "Save and return to course" + And I close the browser tab opened by the app + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" + And I should see "Timeline" + And I press "Add submission" in the app + Then the header should be "assignment" in the app + And I should see "Test assignment description" + And I should see "No attempt" + And I should see "Due date" + And I press "Add submission" in the app + And I set the field "Online text submissions" to "test" in the app + And I press "Save" in the app + And I press "Submit assignment" in the app + And I press "OK" in the app + Then the header should be "assignment" in the app + And I should see "Test assignment description" + And I should see "Submitted for grading" + And I should see "Due date" + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" + And I should see "Timeline" + And I press "Grade" in the app + Then the header should be "assignment" in the app + And I should see "Test assignment description" + And I should see "Time remaining" + And I press "Needs grading" in the app + Then I should see "Student student" + And I should see "Not graded" \ No newline at end of file diff --git a/mod/data/tests/behat/app_data_entries.feature b/mod/data/tests/behat/app_data_entries.feature deleted file mode 100755 index 2517342ef..000000000 --- a/mod/data/tests/behat/app_data_entries.feature +++ /dev/null @@ -1,46 +0,0 @@ -@mod @mod_data @app @javascript -Feature: Trying options moodle mobile - - Background: - Given the following "users" exist: - | username | firstname | lastname | email | - | student1 | Student | 1 | student1@example.com | - | student2 | Student | 2 | student2@example.com | - | teacher1 | Teacher | 1 | teacher1@example.com | - And the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - | student2 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | data | Web links | Useful links | C1 | data1 | - - Scenario: Teacher create an event - Given I enter the app - When I log in as "teacher1" - And I press "calendar" in the app - And I press "close" in the app - And I set the field "name" to "Holidays!" - And I press "No selection" in the app - And I press "Course 1" in the app - Then I press "Show more..." in the app - And I set the field "location" to "Moodle" - And I press "Save" in the app - - Scenario: Student change his moodle language - Given I enter the app - When I log in as "student1" - And I press "more" near "Timeline" in the app - And I press "App settings" in the app - And I press "General" in the app - And I press "Language" in the app - And I press "Español" in the app - And I pause - And I press "Text size" near "Español" in the app - And I pause - - diff --git a/mod/data/tests/behat/app_data_sync.feature b/mod/data/tests/behat/app_data_sync.feature deleted file mode 100755 index 025f1abcc..000000000 --- a/mod/data/tests/behat/app_data_sync.feature +++ /dev/null @@ -1,136 +0,0 @@ -@mod @mod_data @app @javascript -Feature: Users can store entries in database activities when offline and sync when online - In order to populate databases while offline - As a user - I need to add and manage entries to databases and sync then when online - - Background: - Given the following "users" exist: - | username | firstname | lastname | email | - | student1 | Student | 1 | student1@example.com | - | student2 | Student | 2 | student2@example.com | - | teacher1 | Teacher | 1 | teacher1@example.com | - And the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - | student2 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | data | Web links | Useful links | C1 | data1 | - And I log in as "teacher1" - And I am on "Course 1" course homepage - And I add a "Text input" field to "Web links" database and I fill the form with: - | Field name | URL | - | Field description | URL link | - And I add a "Text input" field to "Web links" database and I fill the form with: - | Field name | Description | - | Field description | Link description | - And I log out - - @app_from3.7 - Scenario: Students can add entries to a database in the app while offline - Given I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Web links" near "General" in the app - And I switch offline mode to "true" - And I should see "No entries in database" - When I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - Then I should see "https://moodle.org/" - And I should see "Moodle community site" - And I should see "This Database has offline data to be synchronised" - And I press "back" near "Web links" in the app - And I switch offline mode to "false" - And I press "Web links" near "General" in the app - And I should see "https://moodle.org/" - And I should see "Moodle community site" - And I should not see "This Database has offline data to be synchronised" - - @app_from3.7 - Scenario: Students can edit and delete entries to a database in the app while offline - Given I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Web links" near "General" in the app - And I should see "No entries in database" - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - And I should see "https://moodle.org/" - And I should see "Moodle community site" - And I press "Information" in the app - And I press "Download" in the app - And I wait until the page is ready - And I switch offline mode to "true" - When I press "Edit" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - Then I should not see "https://moodle.org/" - And I should not see "Moodle community site" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I should see "This Database has offline data to be synchronised" - And I press "back" near "Web links" in the app - And I switch offline mode to "false" - And I press "Web links" near "General" in the app - And I should not see "https://moodle.org/" - And I should not see "Moodle community site" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I should not see "This Database has offline data to be synchronised" - And I press "Information" in the app - And I press "Refresh" in the app - And I wait until the page is ready - And I switch offline mode to "true" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I should see "This Database has offline data to be synchronised" - And I press "back" near "Web links" in the app - And I switch offline mode to "false" - And I press "Web links" near "General" in the app - And I should not see "https://moodlecloud.com/" - And I should not see "Moodle Cloud" - And I should not see "This Database has offline data to be synchronised" - - @app_from3.7 - Scenario: Students can undo deleting entries to a database in the app while offline - Given I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Web links" near "General" in the app - And I should see "No entries in database" - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - And I should see "https://moodle.org/" - And I should see "Moodle community site" - And I press "Information" in the app - And I press "Download" in the app - And I wait until the page is ready - When I switch offline mode to "true" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app - And I should see "https://moodle.org/" - And I should see "Moodle community site" - And I should see "This Database has offline data to be synchronised" - And I press "Restore" in the app - And I press "back" near "Web links" in the app - And I switch offline mode to "false" - And I press "Web links" near "General" in the app - Then I should see "https://moodle.org/" - And I should see "Moodle community site" - And I should not see "This Database has offline data to be synchronised" diff --git a/mod/quiz/tests/behat/app_quiz_navigation.feature b/mod/quiz/tests/behat/app_quiz_navigation.feature deleted file mode 100755 index 63c0e71be..000000000 --- a/mod/quiz/tests/behat/app_quiz_navigation.feature +++ /dev/null @@ -1,110 +0,0 @@ -@mod @mod_quiz @app @javascript -Feature: Attempt a quiz in app - As a student - In order to demonstrate what I know - I need to be able to attempt quizzes - - Background: - Given the following "courses" exist: - | fullname | shortname | - | Course 1 | C1 | - And the following "users" exist: - | username | - | student1 | - And the following "course enrolments" exist: - | user | course | role | - | student1 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | - And the following "question categories" exist: - | contextlevel | reference | name | - | Course | C1 | Test questions | - And the following "questions" exist: - | questioncategory | qtype | name | questiontext | - | Test questions | truefalse | TF1 | Text of the first question | - | Test questions | truefalse | TF2 | Text of the second question | - And quiz "Quiz 1" contains the following questions: - | question | page | - | TF1 | 1 | - | TF2 | 2 | - - @app_upto3.7.0 - Scenario: Next and previous navigation in the 3.6 app - Given I enter the app - And I log in as "student1" - When I press "Course 1" near "Course overview" in the app - And I press "Quiz 1" in the app - And I press "Attempt quiz now" in the app - Then I should see "Text of the first question" - And I should not see "Text of the second question" - And I press "Next" near "Question 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Previous" near "Question 2" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" - And I press "Next" near "Quiz 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Previous" near "Quiz 1" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" - And I press "Next" near "Question 1" in the app - And I press "Next" near "Quiz 1" in the app - And I should see "Summary of attempt" - And I press "Return to attempt" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Next" in the app - And I press "Submit all and finish" in the app - And I should see "Once you submit" - And I press "Cancel" near "Once you submit" in the app - And I should see "Summary of attempt" - And I press "Submit all and finish" in the app - And I press "OK" near "Once you submit" in the app - And I should see "Review" - And I press "home" in the app - And I should see "Acceptance test site" - - @app_from3.7.1 - Scenario: Next and previous navigation in the 3.7 app - Given I enter the app - And I log in as "student1" - When I press "Course 1" near "Course overview" in the app - And I press "Quiz 1" in the app - And I press "Attempt quiz now" in the app - Then I should see "Text of the first question" - And I should not see "Text of the second question" - And I press "Next" near "Question 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Previous" near "Question 2" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" - And I press "Next" near "Quiz 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Previous" near "Quiz 1" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" - And I press "Next" near "Question 1" in the app - And I press "Next" near "Quiz 1" in the app - And I should see "Summary of attempt" - And I press "Return to attempt" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Next" in the app - And I press "Submit all and finish" in the app - And I should see "Once you submit" - And I press "Cancel" near "Once you submit" in the app - And I should see "Summary of attempt" - And I press "Submit all and finish" in the app - And I press "OK" near "Once you submit" in the app - And I should see "Review" - And I press "home" in the app - And I should see "Are you sure" - And I should see "OK" - And I press "OK" in the app - And I pause - And I should see "Acceptance test site" \ No newline at end of file From 72dae3cadf8271f2201cf686c3ee5980611e31a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Tue, 21 Jan 2020 11:30:36 +0100 Subject: [PATCH 033/220] MOBILE-3307 behat: Behat basic test for course --- .../tests/behat/app_basic_usage.feature | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100755 mod/course/tests/behat/app_basic_usage.feature diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature new file mode 100755 index 000000000..30794447b --- /dev/null +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -0,0 +1,154 @@ +@mod @mod_course @app @javascript +Feature: Test basic usage of one course in app + In order to participate in one course while using the mobile app + As a student + I need basic courses functionality to work + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student | student | student1@example.com | + + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | option | + | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | + + And the following "activities" exist: + | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | + | assign | C1 | assign1 | assignment | Test assignment description | 1 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | assessed | scale[modgrade_type] | + | forum | Test forum name | Test forum | C1 | forum | 0 | 5 | Point | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | chat | Test chat name | Test chat | C1 | chat | 0 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | data | Web links | Useful links | C1 | data1 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | lti | Test external name | Test external | C1 | external | 0 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | feedback | Test feedback name | Test feedback | C1 | feedback | 0 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | glossary | Test glossary | glossary description | C1 | gloss1 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | + And the following "question categories" exist: + | contextlevel | reference | name | + | Course | C1 | Test questions | + And the following "questions" exist: + | questioncategory | qtype | name | questiontext | + | Test questions | truefalse | TF1 | Text of the first question | + | Test questions | truefalse | TF2 | Text of the second question | + And quiz "Quiz 1" contains the following questions: + | question | page | + | TF1 | 1 | + | TF2 | 2 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | survey | Test survey name | Test survey | C1 | survey | 0 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | wiki | Test wiki name | Test wiki | C1 | wiki | 0 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | lesson | Test lesson name | Test lesson | C1 | lesson | 0 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | scorm | Test scorm name | Test scorm | C1 | scorm | 0 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | workshop | Test workshop name | Test workshop | C1 | workshop | 0 | + + @app @3.8.0 @OK + Scenario: Student views course contents + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test external name" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" + And I press "Choice course 1" in the app + Then the header should be "Choice course 1" in the app + And I press the back button in the app + And I press "assignment" in the app + Then the header should be "assignment" in the app + And I press the back button in the app + And I press "Test forum name" in the app + Then the header should be "Test forum name" in the app + And I press the back button in the app + And I press "Test chat name" in the app + Then the header should be "Test chat name" in the app + And I press the back button in the app + And I press "Web links" in the app + Then the header should be "Web links" in the app + And I press the back button in the app + And I press "Test external name" in the app + Then the header should be "Test external name" in the app + And I press the back button in the app + And I press "Test feedback name" in the app + And I press "OK" in the app + Then the header should be "Test feedback name" in the app + And I press the back button in the app + And I press "Test glossary" in the app + Then the header should be "Test glossary" in the app + And I press the back button in the app + And I press "Quiz 1" in the app + Then the header should be "Quiz 1" in the app + And I press the back button in the app + And I press "Test survey name" in the app + Then the header should be "Test survey name" in the app + And I press the back button in the app + And I press "Test wiki name" in the app + And I press "OK" in the app + Then the header should be "Test wiki name" in the app + And I press the back button in the app + And I press "Test lesson name" in the app + Then the header should be "Test lesson name" in the app + And I press the back button in the app + And I press "Test scorm name" in the app + Then the header should be "Test scorm name" in the app + And I press the back button in the app + And I press "Test workshop name" in the app + Then the header should be "Test workshop name" in the app + And I press the back button in the app \ No newline at end of file From 57cc2e5b20f8740780ef54c53ee384726853cbb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 22 Jan 2020 09:42:59 +0100 Subject: [PATCH 034/220] MOBILE-3307 behat: Behat basic test for course --- .../tests/behat/app_basic_usage.feature | 213 ++++++++++++++++-- 1 file changed, 188 insertions(+), 25 deletions(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 30794447b..e6f0e517e 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -20,45 +20,45 @@ Feature: Test basic usage of one course in app | student1 | C1 | student | And the following "activities" exist: - | activity | name | intro | course | idnumber | option | - | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | + | activity | name | intro | course | idnumber | option | section | + | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 1 | And the following "activities" exist: - | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | - | assign | C1 | assign1 | assignment | Test assignment description | 1 | + | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | section | + | assign | C1 | assign1 | assignment | Test assignment description | 1 | 1 | And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | assessed | scale[modgrade_type] | | forum | Test forum name | Test forum | C1 | forum | 0 | 5 | Point | And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | - | chat | Test chat name | Test chat | C1 | chat | 0 | + | activity | name | intro | course | idnumber | groupmode | section | + | chat | Test chat name | Test chat | C1 | chat | 0 | 2 | And the following "activities" exist: - | activity | name | intro | course | idnumber | - | data | Web links | Useful links | C1 | data1 | + | activity | name | intro | course | idnumber | section | + | data | Web links | Useful links | C1 | data1 | 4 | And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | - | lti | Test external name | Test external | C1 | external | 0 | + | activity | name | intro | course | idnumber | groupmode | section | + | lti | Test external name | Test external | C1 | external | 0 | 1 | And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | - | feedback | Test feedback name | Test feedback | C1 | feedback | 0 | + | activity | name | intro | course | idnumber | groupmode | section | + | feedback | Test feedback name | Test feedback | C1 | feedback | 0 | 3 | And the following "activities" exist: - | activity | name | intro | course | idnumber | - | glossary | Test glossary | glossary description | C1 | gloss1 | + | activity | name | intro | course | idnumber | section | + | glossary | Test glossary | glossary description | C1 | gloss1 | 5 | And the following "activities" exist: - | activity | name | intro | course | idnumber | - | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | + | activity | name | intro | course | idnumber | section | + | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 2 | And the following "question categories" exist: | contextlevel | reference | name | | Course | C1 | Test questions | And the following "questions" exist: - | questioncategory | qtype | name | questiontext | + | questioncategory | qtype | name | questiontext | | Test questions | truefalse | TF1 | Text of the first question | | Test questions | truefalse | TF2 | Text of the second question | And quiz "Quiz 1" contains the following questions: @@ -67,24 +67,24 @@ Feature: Test basic usage of one course in app | TF2 | 2 | And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | - | survey | Test survey name | Test survey | C1 | survey | 0 | + | activity | name | intro | course | idnumber | groupmode | section | + | survey | Test survey name | Test survey | C1 | survey | 0 | 1 | And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | | wiki | Test wiki name | Test wiki | C1 | wiki | 0 | And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | - | lesson | Test lesson name | Test lesson | C1 | lesson | 0 | + | activity | name | intro | course | idnumber | groupmode | section | + | lesson | Test lesson name | Test lesson | C1 | lesson | 0 | 3 | And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | - | scorm | Test scorm name | Test scorm | C1 | scorm | 0 | + | activity | name | intro | course | idnumber | groupmode | section | + | scorm | Test scorm name | Test scorm | C1 | scorm | 0 | 2 | And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | - | workshop | Test workshop name | Test workshop | C1 | workshop | 0 | + | activity | name | intro | course | idnumber | groupmode | section | + | workshop | Test workshop name | Test workshop | C1 | workshop | 0 | 3 | @app @3.8.0 @OK Scenario: Student views course contents @@ -151,4 +151,167 @@ Feature: Test basic usage of one course in app And I press the back button in the app And I press "Test workshop name" in the app Then the header should be "Test workshop name" in the app + And I press the back button in the app + + @app @3.8.0 @OK + Scenario: Student views section contents + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test external name" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" + And I press "arrow dropdown" in the app + And I press "General" near "Sections" in the app + Then I should not see "Choice course 1" + And I should not see "assignment" + And I should see "Test forum name" + And I should not see "Test chat name" + And I should not see "Web links" + And I should not see "Test external name" + And I should not see "Test feedback name" + And I should not see "Test glossary" + And I should not see "Quiz 1" + And I should not see "Test survey name" + And I should see "Test wiki name" + And I should not see "Test lesson name" + And I should not see "Test scorm name" + And I should not see "Test workshop name" + And I press "Test forum name" in the app + Then the header should be "Test forum name" in the app + And I press the back button in the app + And I press "Test wiki name" in the app + And I press "OK" in the app + Then the header should be "Test wiki name" in the app + And I press the back button in the app + And I press "arrow dropdown" in the app + And I press "Topic 1" near "Sections" in the app + Then I should see "Choice course 1" + And I should see "assignment" + And I should not see "Test forum name" + And I should not see "Test chat name" + And I should not see "Web links" + And I should see "Test external name" + And I should not see "Test feedback name" + And I should not see "Test glossary" + And I should not see "Quiz 1" + And I should see "Test survey name" + And I should not see "Test wiki name" + And I should not see "Test lesson name" + And I should not see "Test scorm name" + And I should not see "Test workshop name" + And I press "Choice course 1" in the app + Then the header should be "Choice course 1" in the app + And I press the back button in the app + And I press "assignment" in the app + Then the header should be "assignment" in the app + And I press the back button in the app + And I press "Test external name" in the app + Then the header should be "Test external name" in the app + And I press the back button in the app + And I press "Test survey name" in the app + Then the header should be "Test survey name" in the app + And I press the back button in the app + And I press "arrow dropdown" in the app + And I press "Topic 2" near "Sections" in the app + Then I should not see "Choice course 1" + And I should not see "assignment" + And I should not see "Test forum name" + And I should see "Test chat name" + And I should not see "Web links" + And I should not see "Test external name" + And I should not see "Test feedback name" + And I should not see "Test glossary" + And I should see "Quiz 1" + And I should not see "Test survey name" + And I should not see "Test wiki name" + And I should not see "Test lesson name" + And I should see "Test scorm name" + And I should not see "Test workshop name" + And I press "Test chat name" in the app + Then the header should be "Test chat name" in the app + And I press the back button in the app + And I press "Quiz 1" in the app + Then the header should be "Quiz 1" in the app + And I press the back button in the app + And I press "Test scorm name" in the app + Then the header should be "Test scorm name" in the app + And I press the back button in the app + And I press "arrow dropdown" in the app + And I press "Topic 3" near "Sections" in the app + Then I should not see "Choice course 1" + And I should not see "assignment" + And I should not see "Test forum name" + And I should not see "Test chat name" + And I should not see "Web links" + And I should not see "Test external name" + And I should see "Test feedback name" + And I should not see "Test glossary" + And I should not see "Quiz 1" + And I should not see "Test survey name" + And I should not see "Test wiki name" + And I should see "Test lesson name" + And I should not see "Test scorm name" + And I should see "Test workshop name" + And I press "Test feedback name" in the app + And I press "OK" in the app + Then the header should be "Test feedback name" in the app + And I press the back button in the app + And I press "Test lesson name" in the app + Then the header should be "Test lesson name" in the app + And I press the back button in the app + And I press "Test workshop name" in the app + Then the header should be "Test workshop name" in the app + And I press the back button in the app + And I press "arrow dropdown" in the app + And I press "Topic 4" near "Sections" in the app + Then I should not see "Choice course 1" + And I should not see "assignment" + And I should not see "Test forum name" + And I should not see "Test chat name" + And I should see "Web links" + And I should not see "Test external name" + And I should not see "Test feedback name" + And I should not see "Test glossary" + And I should not see "Quiz 1" + And I should not see "Test survey name" + And I should not see "Test wiki name" + And I should not see "Test lesson name" + And I should not see "Test scorm name" + And I should not see "Test workshop name" + And I press "Web links" in the app + Then the header should be "Web links" in the app + And I press the back button in the app + And I press "arrow dropdown" in the app + And I press "Topic 5" near "Sections" in the app + Then I should not see "Choice course 1" + And I should not see "assignment" + And I should not see "Test forum name" + And I should not see "Test chat name" + And I should not see "Web links" + And I should not see "Test external name" + And I should not see "Test feedback name" + And I should see "Test glossary" + And I should not see "Quiz 1" + And I should not see "Test survey name" + And I should not see "Test wiki name" + And I should not see "Test lesson name" + And I should not see "Test scorm name" + And I should not see "Test workshop name" + And I press "Test glossary" in the app + Then the header should be "Test glossary" in the app And I press the back button in the app \ No newline at end of file From 3cf915376ba48a83b1686c41def143696f2726cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 22 Jan 2020 10:48:15 +0100 Subject: [PATCH 035/220] MOBILE-3307 behat: Behat basic test for course --- .../tests/behat/app_basic_usage.feature | 75 ++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index e6f0e517e..b4d453a42 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -314,4 +314,77 @@ Feature: Test basic usage of one course in app And I should not see "Test workshop name" And I press "Test glossary" in the app Then the header should be "Test glossary" in the app - And I press the back button in the app \ No newline at end of file + And I press the back button in the app + + @app @3.8.0 @OK + Scenario: Navigation between sections using the bottom arrows + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test external name" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" + And I press "arrow dropdown" in the app + And I press "General" near "Sections" in the app + Then I should see "General" + And I should not see "Topic 1" + And I should not see "Topic 2" + And I should not see "Topic 3" + And I should not see "Topic 4" + And I should not see "Topic 5" + And I press "arrow forward" near "Test wiki name" in the app + Then I should not see "General" + And I should see "Topic 1" + And I should not see "Topic 2" + And I should not see "Topic 3" + And I should not see "Topic 4" + And I should not see "Topic 5" + And I press "arrow forward" near "Test survey name" in the app + Then I should not see "General" + And I should not see "Topic 1" + And I should see "Topic 2" + And I should not see "Topic 3" + And I should not see "Topic 4" + And I should not see "Topic 5" + And I press "arrow forward" near "Test scorm name" in the app + Then I should not see "General" + And I should not see "Topic 1" + And I should not see "Topic 2" + And I should see "Topic 3" + And I should not see "Topic 4" + And I should not see "Topic 5" + And I press "arrow forward" near "Test workshop name" in the app + Then I should not see "General" + And I should not see "Topic 1" + And I should not see "Topic 2" + And I should not see "Topic 3" + And I should see "Topic 4" + And I should not see "Topic 5" + And I press "arrow forward" near "Web links" in the app + Then I should not see "General" + And I should not see "Topic 1" + And I should not see "Topic 2" + And I should not see "Topic 3" + And I should not see "Topic 4" + And I should see "Topic 5" + And I press "arrow back" near "Test glossary" in the app + Then I should not see "General" + And I should not see "Topic 1" + And I should not see "Topic 2" + And I should not see "Topic 3" + And I should see "Topic 4" + And I should not see "Topic 5" \ No newline at end of file From 8db0829bd3b128a09b1887e3054e11e79ffd9c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 23 Jan 2020 09:49:05 +0100 Subject: [PATCH 036/220] MOBILE-3307 behat: Behat basic test for course --- .../tests/behat/app_basic_usage.feature | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index b4d453a42..98af9e0fa 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -9,6 +9,7 @@ Feature: Test basic usage of one course in app | username | firstname | lastname | email | | teacher1 | Teacher | teacher | teacher1@example.com | | student1 | Student | student | student1@example.com | + | student2 | Student2 | student2 | student2@example.com | And the following "courses" exist: | fullname | shortname | category | @@ -315,7 +316,7 @@ Feature: Test basic usage of one course in app And I press "Test glossary" in the app Then the header should be "Test glossary" in the app And I press the back button in the app - + @app @3.8.0 @OK Scenario: Navigation between sections using the bottom arrows When I enter the app @@ -387,4 +388,49 @@ Feature: Test basic usage of one course in app And I should not see "Topic 2" And I should not see "Topic 3" And I should see "Topic 4" - And I should not see "Topic 5" \ No newline at end of file + And I should not see "Topic 5" + + @app @3.8.0 @OK + Scenario: Self enrol + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Information" in the app + And I press "Course summary" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "More..." + And I follow "Users" + And I follow "Enrolment methods" + And I follow "Delete" + And I press "Continue" + And I follow "Enable" + And I close the browser tab opened by the app + When I enter the app + And I log in as "student2" + Then the header should be "Acceptance test site" in the app + And I press "Site home" in the app + And I press "Available courses" in the app + And I press "Course 1" in the app + And I press "Enrol me" in the app + And I press "OK" in the app + And I press "Contents" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test external name" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" \ No newline at end of file From b263552d9cb8772e266682883e93750db9940b90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 23 Jan 2020 10:27:26 +0100 Subject: [PATCH 037/220] MOBILE-3307 behat: Behat basic test for course --- .../tests/behat/app_basic_usage.feature | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 98af9e0fa..7a8401683 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -433,4 +433,46 @@ Feature: Test basic usage of one course in app And I should see "Test wiki name" And I should see "Test lesson name" And I should see "Test scorm name" + And I should see "Test workshop name" + + @app @3.8.0 @OK + Scenario: Guest access + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Information" in the app + And I press "Course summary" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "More..." + And I follow "Users" + And I follow "Enrolment methods" + And I follow "Enable" + And I close the browser tab opened by the app + When I enter the app + And I log in as "student2" + Then the header should be "Acceptance test site" in the app + And I press "Site home" in the app + And I press "Available courses" in the app + And I press "Course 1" in the app + Then I should see "Download course" + And I should see "Contents" + And I press "Contents" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" And I should see "Test workshop name" \ No newline at end of file From ab223d6a0a9847c495f03d9bea58cbcd88b73f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 23 Jan 2020 12:43:10 +0100 Subject: [PATCH 038/220] MOBILE-3307 behat: Behat basic test for course --- .../tests/behat/app_basic_usage.feature | 102 +++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 7a8401683..66f79b1a7 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -475,4 +475,104 @@ Feature: Test basic usage of one course in app And I should see "Test wiki name" And I should see "Test lesson name" And I should see "Test scorm name" - And I should see "Test workshop name" \ No newline at end of file + And I should see "Test workshop name" + + @app @3.8.0 @mobile @OK + Scenario: View blocks bellow/beside contents also when All sections selected (mobile) + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Information" in the app + And I press "Course summary" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "Turn editing on" + And I click on "Side panel" "button" + And I follow "Add a block" + And I follow "HTML" + And I click on "Side panel" "button" + And I follow "Add a block" + And I follow "Activities" + And I click on "Actions menu" "icon" in the "#dropdown-0" "css_element" + And I follow "Configure (new HTML block) block" + And I set the field "HTML block title" to "HTML title test" + And I set the field "Content" to "body test" + And I press "Save changes" + And I close the browser tab opened by the app + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test external name" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" + Then I should see "HTML title test" + And I should see "body test" + And I should see "Activities" + + @app @3.8.0 @tablet @OK + Scenario: View blocks bellow/beside contents also when All sections selected (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Information" in the app + And I press "Course summary" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "Turn editing on" + And I follow "Add a block" + And I follow "HTML" + And I follow "Add a block" + And I follow "Activities" + And I click on "Actions menu" "icon" in the "#dropdown-0" "css_element" + And I follow "Configure (new HTML block) block" + And I set the field "HTML block title" to "HTML title test" + And I set the field "Content" to "body test" + And I press "Save changes" + And I close the browser tab opened by the app + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test external name" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" + Then I should see "HTML title test" + And I should see "body test" + And I should see "Activities" \ No newline at end of file From 57f52a8c6000849694b710c437842f13046d25e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Fri, 24 Jan 2020 12:00:17 +0100 Subject: [PATCH 039/220] MOBILE-3307 MOBILE-3319 behat: Behat basic test for messages and an improvement on course --- .../tests/behat/app_basic_usage.feature | 10 +- .../tests/behat/app_basic_usage.feature | 95 +++++++++++++++++++ 2 files changed, 99 insertions(+), 6 deletions(-) create mode 100755 mod/messages/tests/behat/app_basic_usage.feature diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 66f79b1a7..7452476e0 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -2,7 +2,7 @@ Feature: Test basic usage of one course in app In order to participate in one course while using the mobile app As a student - I need basic courses functionality to work + I need basic course functionality to work Background: Given the following "users" exist: @@ -406,9 +406,7 @@ Feature: Test basic usage of one course in app And I follow "More..." And I follow "Users" And I follow "Enrolment methods" - And I follow "Delete" - And I press "Continue" - And I follow "Enable" + And I click on "Enable" "icon" in the "Self enrolment (Student)" "table_row" And I close the browser tab opened by the app When I enter the app And I log in as "student2" @@ -434,7 +432,7 @@ Feature: Test basic usage of one course in app And I should see "Test lesson name" And I should see "Test scorm name" And I should see "Test workshop name" - + @app @3.8.0 @OK Scenario: Guest access When I enter the app @@ -451,7 +449,7 @@ Feature: Test basic usage of one course in app And I follow "More..." And I follow "Users" And I follow "Enrolment methods" - And I follow "Enable" + And I click on "Enable" "icon" in the "Guest access" "table_row" And I close the browser tab opened by the app When I enter the app And I log in as "student2" diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature new file mode 100755 index 000000000..142f4dd63 --- /dev/null +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -0,0 +1,95 @@ +@mod @mod_messages @app @javascript +Feature: Test basic usage of messages in app + In order to participate with messages while using the mobile app + As a student + I need basic messages functionality to work + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student1 | student1 | student1@example.com | + | student2 | Student2 | student2 | student2@example.com | + + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + + + @app @3.8.0 @mobile @OK + Scenario: View recent conversations and contacts (mobile) + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + Then I should see "No contacts" + And I press "addon.messages.search" in the app + And I set the field "Search" to "student" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I press "Conversation actions menu" in the app + And I press "Add to contacts" in the app + And I press "Add" in the app + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "Requests" in the app + And I press "Teacher teacher" in the app + And I press "Accept and add to contacts" in the app + And I press the back button in the app + And I press "Contacts" near "Requests" in the app + Then the header should be "Contacts" in the app + And I should see "Teacher teacher" + And I press the back button in the app + And I press "Teacher teacher" in the app + Then the header should be "Teacher teacher" in the app + And I should see "heeey student" + + @app @3.8.0 @tablet @OK + Scenario: View recent conversations and contacts (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + Then I should see "No contacts" + And I press "addon.messages.search" in the app + And I set the field "Search" to "student" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I press "Information" in the app + And I press "Add to contacts" in the app + And I press "Add" in the app + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "Requests" in the app + And I press "Teacher teacher" in the app + And I press "Accept and add to contacts" in the app + And I press "Contacts" near "Requests" in the app + Then the header should be "Contacts" in the app + And I should see "Teacher teacher" + And I press the back button in the app + And I press "Teacher teacher" in the app + And I should see "heeey student" \ No newline at end of file From 5b007b0125abd298d70e1f567ee9907d6ba1c3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Fri, 24 Jan 2020 12:17:36 +0100 Subject: [PATCH 040/220] MOBILE-3319 behat: Behat basic test for messages --- .../tests/behat/app_basic_usage.feature | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index 142f4dd63..e03fe7502 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -92,4 +92,19 @@ Feature: Test basic usage of messages in app And I should see "Teacher teacher" And I press the back button in the app And I press "Teacher teacher" in the app - And I should see "heeey student" \ No newline at end of file + And I should see "heeey student" + + @app @3.8.0 @OK + Scenario: Search users + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student2" in the app + And I press "search" in the app + Then I should see "Student2 student2" + And I set the field "Search" to "Teacher" in the app + And I press "search" in the app + Then I should see "Teacher teacher" \ No newline at end of file From f30e176a13504e47a68ad5f8a8ad2022f3967c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 27 Jan 2020 09:15:14 +0100 Subject: [PATCH 041/220] MOBILE-3319 behat: Behat basic test for messages --- .../tests/behat/app_basic_usage.feature | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index e03fe7502..54cc8ea20 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -86,7 +86,7 @@ Feature: Test basic usage of messages in app And I press "Contacts" in the app And I press "Requests" in the app And I press "Teacher teacher" in the app - And I press "Accept and add to contacts" in the app + And I press "Accept and add to contacts" in the appa And I press "Contacts" near "Requests" in the app Then the header should be "Contacts" in the app And I should see "Teacher teacher" @@ -107,4 +107,52 @@ Feature: Test basic usage of messages in app Then I should see "Student2 student2" And I set the field "Search" to "Teacher" in the app And I press "search" in the app - Then I should see "Teacher teacher" \ No newline at end of file + Then I should see "Teacher teacher" + + @app @3.8.0 @OK + Scenario: Send/receive messages in existing conversations + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + Then I should see "No contacts" + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + Then I should see "No contacts" + And I press "addon.messages.search" in the app + And I set the field "Search" to "teacher" in the app + And I press "search" in the app + And I press "Teacher teacher" in the app + Then I should see "heeey student" + And I set the field "New message" to "hi" in the app + And I press "Send" in the app + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + Then I should see "No contacts" + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + Then I should see "heeey student" + And I should see "hi" + And I set the field "New message" to "byee" in the app + And I press "Send" in the app + Then I should see "heeey student" + And I should see "hi" + And I should see "byee" \ No newline at end of file From c4c665badcb34f733160d0f09291e87b17087c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 27 Jan 2020 09:17:55 +0100 Subject: [PATCH 042/220] MOBILE-3319 behat: Behat basic test for messages --- mod/messages/tests/behat/app_basic_usage.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index 54cc8ea20..f7b446a8a 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -86,7 +86,7 @@ Feature: Test basic usage of messages in app And I press "Contacts" in the app And I press "Requests" in the app And I press "Teacher teacher" in the app - And I press "Accept and add to contacts" in the appa + And I press "Accept and add to contacts" in the app And I press "Contacts" near "Requests" in the app Then the header should be "Contacts" in the app And I should see "Teacher teacher" From 529206bbaf7218cce123c57aea34f4ef4647732e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 27 Jan 2020 10:39:37 +0100 Subject: [PATCH 043/220] MOBILE-3319 behat: Behat basic test for messages --- .../tests/behat/app_basic_usage.feature | 96 ++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index f7b446a8a..8c94bc1cb 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -155,4 +155,98 @@ Feature: Test basic usage of messages in app And I press "Send" in the app Then I should see "heeey student" And I should see "hi" - And I should see "byee" \ No newline at end of file + And I should see "byee" + + @app @3.8.0 @OK + Scenario: User profile, send message, add/remove contact (mobile) + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + Then I should see "No contacts" + And I press "addon.messages.search" in the app + And I set the field "Search" to "student" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I press "Conversation actions menu" in the app + And I press "Add to contacts" in the app + And I press "Add" in the app + Then I should see "Contact request sent" + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "Requests" in the app + And I press "Teacher teacher" in the app + Then I should see "Teacher teacher would like to contact you" + And I press "Accept and add to contacts" in the app + And I should not see "Teacher teacher would like to contact you" + And I press "Teacher teacher" in the app + And I press "Message" in the app + And I set the field "New message" to "hi" in the app + And I press "Send" in the app + Then I should see "heeey student" + And I should see "hi" + And I press the back button in the app + And I press "Remove from contacts" in the app + And I press "Remove" in the app + Then I should see "Add to contacts" + And I press the back button in the app + And I press "Conversation actions menu" in the app + Then I should see "Add to contacts" + And I press "Delete conversation" in the app + And I press "Delete" in the app + And I should not see "heeey student" + And I should not see "hi" + + @app @3.8.0 @OK + Scenario: User profile, send message, add/remove contact (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + Then I should see "No contacts" + And I press "addon.messages.search" in the app + And I set the field "Search" to "student" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I press "Information" in the app + And I press "Add to contacts" in the app + And I press "Add" in the app + Then I should see "Contact request sent" + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "Requests" in the app + And I press "Teacher teacher" in the app + Then I should see "Teacher teacher would like to contact you" + And I press "Accept and add to contacts" in the app + And I should not see "Teacher teacher would like to contact you" + And I set the field "New message" to "hi" in the app + And I press "Send" in the app + Then I should see "heeey student" + And I should see "hi" + And I press "Information" in the app + And I press "Remove from contacts" in the app + And I press "Remove" in the app + And I press "Information" in the app + Then I should see "Add to contacts" + And I press "Delete conversation" in the app + And I press "Delete" in the app + And I should not see "heeey student" + And I should not see "hi" \ No newline at end of file From 84e9f6ce6f27a24394e8bd500f1437fe12a783a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 27 Jan 2020 12:05:36 +0100 Subject: [PATCH 044/220] MOBILE-3319 behat: Behat basic test for messages --- .../tests/behat/app_basic_usage.feature | 67 ++++++++++++++++++- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index 8c94bc1cb..9d373037d 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -157,7 +157,7 @@ Feature: Test basic usage of messages in app And I should see "hi" And I should see "byee" - @app @3.8.0 @OK + @app @3.8.0 @mobile @OK Scenario: User profile, send message, add/remove contact (mobile) When I enter the app And I log in as "teacher1" @@ -205,7 +205,7 @@ Feature: Test basic usage of messages in app And I should not see "heeey student" And I should not see "hi" - @app @3.8.0 @OK + @app @3.8.0 @tablet @OK Scenario: User profile, send message, add/remove contact (tablet) When I enter the app And I change viewport size to "1280x1080" @@ -249,4 +249,65 @@ Feature: Test basic usage of messages in app And I press "Delete conversation" in the app And I press "Delete" in the app And I should not see "heeey student" - And I should not see "hi" \ No newline at end of file + And I should not see "hi" + + @app @3.8.0 @mobile @OK + Scenario: Send message offline (mobile) + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + Then I should see "No contacts" + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I switch offline mode to "true" + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I set the field "New message" to "byee" in the app + And I press "Send" in the app + And I switch offline mode to "false" + And I press the back button in the app + And I press "Student1 student1" in the app + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Teacher teacher" in the app + Then I should see "heeey student" + And I should see "byee" + + @app @3.8.0 @tablet @OK + Scenario: Send message offline (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + Then I should see "No contacts" + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I switch offline mode to "true" + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I set the field "New message" to "byee" in the app + And I press "Send" in the app + And I switch offline mode to "false" + And I press "Student1 student1" in the app + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Teacher teacher" in the app + Then I should see "heeey student" + And I should see "byee" \ No newline at end of file From 9e052a56222d47cea6d28c8205b0bbb91320b21f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Tue, 28 Jan 2020 09:44:15 +0100 Subject: [PATCH 045/220] MOBILE-3319 behat: Behat basic test for messages --- .../tests/behat/app_basic_usage.feature | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index 9d373037d..666938df7 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -2,7 +2,7 @@ Feature: Test basic usage of messages in app In order to participate with messages while using the mobile app As a student - I need basic messages functionality to work + I need basic message functionality to work Background: Given the following "users" exist: @@ -310,4 +310,33 @@ Feature: Test basic usage of messages in app And I press "Messages" in the app And I press "Teacher teacher" in the app Then I should see "heeey student" - And I should see "byee" \ No newline at end of file + And I should see "byee" + + @app @3.8.0 @OK + Scenario: Search for messages + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "test message" in the app + And I press "Send" in the app + And I set the field "New message" to "search this message" in the app + And I press "Send" in the app + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "search this message" in the app + And I press "search" in the app + Then I should see "Messages" + And I should see "search this message" + And I press "search this message" near "Teacher teacher" in the app + Then I should see "test message" + And I should see "search this message" \ No newline at end of file From 05a92a6088ac841aedfb38fa9e2f7305398d7089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Tue, 28 Jan 2020 10:43:11 +0100 Subject: [PATCH 046/220] MOBILE-3319 behat: Behat basic test for messages --- .../tests/behat/app_basic_usage.feature | 86 ++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index 666938df7..6c3744ac4 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -339,4 +339,88 @@ Feature: Test basic usage of messages in app And I should see "search this message" And I press "search this message" near "Teacher teacher" in the app Then I should see "test message" - And I should see "search this message" \ No newline at end of file + And I should see "search this message" + + @app @3.8.0 @mobile @OK + Scenario: Star/Unstar (mobile) + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "star message" in the app + And I press "Send" in the app + When I enter the app + And I log in as "student2" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "test message student2" in the app + And I press "Send" in the app + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + Then I should see "Private (2)" + And I should see "Starred (1)" + And I press "star message" in the app + And I press "Conversation actions menu" in the app + And I press "Star conversation" in the app + And I press the back button in the app + Then I should see "Private (1)" + And I should see "Starred (2)" + And I press "Starred (2)" in the app + Then I should see "Teacher teacher" + And I should see "Student1 student1" + + @app @3.8.0 @tablet @OK + Scenario: Star/Unstar (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "star message" in the app + And I press "Send" in the app + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student2" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "test message student2" in the app + And I press "Send" in the app + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + Then I should see "Private (2)" + And I should see "Starred (1)" + And I press "star message" in the app + And I press "Information" in the app + And I press "Star conversation" in the app + Then I should see "Private (1)" + And I should see "Starred (2)" + And I press "Starred (2)" in the app + Then I should see "Teacher teacher" + And I should see "Student1 student1" \ No newline at end of file From b30f8ab4d1c3e4813da06ced5ba87e7a2004352a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Tue, 28 Jan 2020 12:01:42 +0100 Subject: [PATCH 047/220] MOBILE-3319 behat: Behat basic test for messages --- .../tests/behat/app_basic_usage.feature | 118 +++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index 6c3744ac4..f4948ce71 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -423,4 +423,120 @@ Feature: Test basic usage of messages in app And I should see "Starred (2)" And I press "Starred (2)" in the app Then I should see "Teacher teacher" - And I should see "Student1 student1" \ No newline at end of file + And I should see "Student1 student1" + + @app @3.8.0 @mobile @OK + Scenario: User blocking feature (mobile) + When I enter the app + And I log in as "student2" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student1 student1" in the app + Then I should see "Block user" + And I press "Block user" in the app + And I should see "Are you sure you want to block Student1 student1?" + And I press "Cancel" in the app + And I should see "Block user" + And I press "Block user" in the app + And I press "Block user" near "Cancel" in the app + Then I should not see "Block user" + And I should see "Unblock user" + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student2 student2" in the app + And I press "Message" in the app + Then I should see "You are unable to message this user" + When I enter the app + And I log in as "student2" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student1 student1" in the app + Then I should see "Unblock user" + And I should not see "Block user" + And I press "Unblock user" in the app + And I press "Cancel" in the app + Then I should see "Unblock user" + And I should not see "Block user" + And I press "Unblock user" in the app + And I press "Unblock user" near "Cancel" in the app + Then I should see "Block user" + And I should not see "Unblock user" + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student2 student2" in the app + And I press "Message" in the app + And I set the field "New message" to "test message" in the app + And I press "Send" in the app + Then I should see "test message" + And I should not see "You are unable to message this user" + + @app @3.8.0 @tablet @OK + Scenario: User blocking feature (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student2" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + Then I should see "Block user" + And I press "Block user" in the app + And I should see "Are you sure you want to block Student1 student1?" + And I press "Cancel" in the app + And I should see "Block user" + And I press "Block user" in the app + And I press "Block user" near "Cancel" in the app + Then I should not see "Block user" + And I should see "Unblock user" + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student2 student2" in the app + And I press "Message" in the app + Then I should see "You are unable to message this user" + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student2" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + Then I should see "Unblock user" + And I should not see "Block user" + And I press "Unblock user" in the app + And I press "Cancel" in the app + Then I should see "Unblock user" + And I should not see "Block user" + And I press "Unblock user" in the app + And I press "Unblock user" near "Cancel" in the app + Then I should see "Block user" + And I should not see "Unblock user" + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student2 student2" in the app + And I press "Message" in the app + And I set the field "New message" to "test message" in the app + And I press "Send" in the app + Then I should see "test message" + And I should not see "You are unable to message this user" \ No newline at end of file From 18282d8045cbd4e00ca14354c039094bcc7d6f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 29 Jan 2020 09:21:59 +0100 Subject: [PATCH 048/220] MOBILE-3319 behat: Behat basic test for messages --- .../tests/behat/app_basic_usage.feature | 63 ++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index f4948ce71..c6d6b15c2 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -539,4 +539,65 @@ Feature: Test basic usage of messages in app And I set the field "New message" to "test message" in the app And I press "Send" in the app Then I should see "test message" - And I should not see "You are unable to message this user" \ No newline at end of file + And I should not see "You are unable to message this user" + + @app @3.8.0 @mobile @OK + Scenario: Mute Unmute conversations (mobile) + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student2 student2" in the app + And I press "Message" in the app + And I set the field "New message" to "test message" in the app + And I press "Send" in the app + And I press "Conversation actions menu" in the app + And I press "Mute" in the app + And I press "Muted conversation" in the app + And I press "Conversation actions menu" in the app + Then I should see "Unmute" + And I should not see "Mute" + And I press "Unmute" in the app + And I press "Conversation actions menu" in the app + Then I should not see "Unmute" + And I should see "Mute" + And I press "Mute" in the app + And I press "Messages" in the app + And I press "Private (1)" in the app + And I press "Student2 student2" in the app + And I press "Conversation actions menu" in the app + Then I should see "Unmute" + And I should not see "Mute" + + @app @3.8.0 @tablet @OK + Scenario: Mute Unmute conversations (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student2 student2" in the app + And I press "Message" in the app + And I set the field "New message" to "test message" in the app + And I press "Send" in the app + And I press "Conversation actions menu" in the app + And I press "Mute" in the app + And I press "Muted conversation" in the app + And I press "Conversation actions menu" in the app + Then I should see "Unmute" + And I should not see "Mute" + And I press "Unmute" in the app + And I press "Conversation actions menu" in the app + Then I should not see "Unmute" + And I should see "Mute" + And I press "Mute" in the app + And I press "Messages" in the app + And I press "Private (1)" in the app + And I press "Student2 student2" in the app + And I press "Information" in the app + Then I should see "Unmute" + And I should not see "Mute" \ No newline at end of file From f5eb3a63a2c47738f0da7cfdc26a6cff06966930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 29 Jan 2020 10:20:46 +0100 Subject: [PATCH 049/220] MOBILE-3319 behat: Behat basic test for messages --- .../tests/behat/app_basic_usage.feature | 102 +++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index c6d6b15c2..89696f64f 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -600,4 +600,104 @@ Feature: Test basic usage of messages in app And I press "Student2 student2" in the app And I press "Information" in the app Then I should see "Unmute" - And I should not see "Mute" \ No newline at end of file + And I should not see "Mute" + + @app @3.8.0 @mobile @OK + Scenario: Self conversations (mobile) + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + Then I should see "Starred (1)" + And I press "Student1 student1" in the app + And I set the field "New message" to "self conversation" in the app + And I press "Send" in the app + And I switch offline mode to "true" + And I set the field "New message" to "self conversation offline" in the app + And I press "Send" in the app + And I switch offline mode to "false" + And I press the back button in the app + And I press "Student1 student1" in the app + And I press "Conversation actions menu" in the app + Then I should see "Unstar conversation" + And I should see "Show delete messages" + And I should see "Delete conversation" + And I press "Unstar conversation" in the app + And I press "Conversation actions menu" in the app + Then I should see "Star conversation" + And I should see "Show delete messages" + And I should see "Delete conversation" + And I press "Show delete messages" in the app + And I should see "self conversation" + And I should see "self conversation offline" + And I press "Delete message" near "self conversation offline" in the app + And I press "OK" in the app + Then I should see "self conversation" + And I should not see "self conversation offline" + And I press "Conversation actions menu" in the app + And I press "Delete conversation" in the app + And I press "Delete" in the app + Then I should not see "self conversation" + And I should not see "self conversation offline" + And I press the back button in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "Student1 student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "auto search test" in the app + And I press "Send" in the app + And I press the back button in the app + And I press the back button in the app + And I press "Private" in the app + And I press "Student1 student1" in the app + Then I should see "auto search test" + + @app @3.8.0 @tablet @OK + Scenario: Self conversations (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + Then I should see "Starred (1)" + And I press "Student1 student1" in the app + And I set the field "New message" to "self conversation" in the app + And I press "Send" in the app + And I switch offline mode to "true" + And I set the field "New message" to "self conversation offline" in the app + And I press "Send" in the app + And I switch offline mode to "false" + And I press "Student1 student1" in the app + And I press "Information" in the app + Then I should see "Unstar conversation" + And I should see "Show delete messages" + And I should see "Delete conversation" + And I press "Unstar conversation" in the app + And I press "Information" in the app + Then I should see "Star conversation" + And I should see "Show delete messages" + And I should see "Delete conversation" + And I press "Show delete messages" in the app + And I should see "self conversation" + And I should see "self conversation offline" + And I press "Delete message" near "self conversation offline" in the app + And I press "OK" in the app + Then I should see "self conversation" + And I should not see "self conversation offline" + And I press "Information" in the app + And I press "Delete conversation" in the app + And I press "Delete" in the app + Then I should not see "self conversation" + And I should not see "self conversation offline" + And I press "addon.messages.search" in the app + And I set the field "Search" to "Student1 student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "auto search test" in the app + And I press "Send" in the app + And I press the back button in the app + And I press "Private" in the app + And I press "Student1 student1" in the app + Then I should see "auto search test" \ No newline at end of file From a5b402c63a7795b7b635684b9bc747674532d354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 29 Jan 2020 11:02:31 +0100 Subject: [PATCH 050/220] MOBILE-3319 behat: Behat basic test for messages --- .../tests/behat/app_basic_usage.feature | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index 89696f64f..a3450d45b 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -312,6 +312,35 @@ Feature: Test basic usage of messages in app Then I should see "heeey student" And I should see "byee" + @app @3.8.0 @OK + Scenario: Auto-sync messages + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Contacts" in the app + Then I should see "No contacts" + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I switch offline mode to "true" + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I set the field "New message" to "byee" in the app + And I press "Send" in the app + And I switch offline mode to "false" + And I wait "600" seconds + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Messages" in the app + And I press "Teacher teacher" in the app + Then I should see "heeey student" + And I should see "byee" + @app @3.8.0 @OK Scenario: Search for messages When I enter the app @@ -425,7 +454,7 @@ Feature: Test basic usage of messages in app Then I should see "Teacher teacher" And I should see "Student1 student1" - @app @3.8.0 @mobile @OK + @app @3.8.0 @mobile @OK Scenario: User blocking feature (mobile) When I enter the app And I log in as "student2" @@ -602,7 +631,7 @@ Feature: Test basic usage of messages in app Then I should see "Unmute" And I should not see "Mute" - @app @3.8.0 @mobile @OK + @app @3.8.0 @mobile @OK Scenario: Self conversations (mobile) When I enter the app And I log in as "student1" From 3e801812f0303d62550053526b71a198df3bb525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 29 Jan 2020 12:10:44 +0100 Subject: [PATCH 051/220] MOBILE-3328 behat: Behat basic test for glossary --- .../tests/behat/app_basic_usage.feature | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100755 mod/glossary/tests/behat/app_basic_usage.feature diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature new file mode 100755 index 000000000..969009a16 --- /dev/null +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -0,0 +1,53 @@ +@mod @mod_glossary @app @javascript +Feature: Test basic usage of glossary in app + In order to participate in the glossaries while using the mobile app + As a student + I need basic glossary functionality to work + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student | student | student1@example.com | + + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | glossary | Test glossary | glossary description | C1 | gloss1 | + + @app @3.8.0 @OK + Scenario: View a glossary and its terms + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I press "car" in the app + Then I should see "car" + And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." \ No newline at end of file From 76df2fa31d6b13a6d05f9ffa4e190cfdb4108d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 30 Jan 2020 09:32:51 +0100 Subject: [PATCH 052/220] MOBILE-3328 behat: Behat basic test for glossary --- .../tests/behat/app_basic_usage.feature | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index 969009a16..03b0f9857 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -50,4 +50,41 @@ Feature: Test basic usage of glossary in app And I should see "potato" And I press "car" in the app Then I should see "car" - And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." \ No newline at end of file + And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." + + @app @3.8.0 @OK + Scenario: Change filters (include search) + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I press "Browse entries" in the app + And I press "Search" in the app + And I set the field "Search query" to "something" in the app + And I press "search" in the app + Then I should see "No entries were found." + And I set the field "Search query" to "potato" in the app + And I press "search" in the app + And I set the field "Search query" to " " in the app + And I press "potato" in the app + Then I should see "potato" + And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." \ No newline at end of file From 94fda27abb2548faf30bf31855c109bad5039178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 5 Feb 2020 09:58:25 +0100 Subject: [PATCH 053/220] MOBILE-3328 behat: Behat basic test for glossary --- .../tests/behat/app_basic_usage.feature | 111 +++++++++++++++++- 1 file changed, 108 insertions(+), 3 deletions(-) diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index 03b0f9857..e8c938621 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -20,8 +20,12 @@ Feature: Test basic usage of glossary in app | student1 | C1 | student | And the following "activities" exist: - | activity | name | intro | course | idnumber | - | glossary | Test glossary | glossary description | C1 | gloss1 | + | activity | name | intro | course | idnumber | mainglossary | allowcomments | + | glossary | Test glossary | glossary description | C1 | gloss1 | 1 | 1 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | forum | Test forum name | Test forum | C1 | forum | 0 | @app @3.8.0 @OK Scenario: View a glossary and its terms @@ -87,4 +91,105 @@ Feature: Test basic usage of glossary in app And I set the field "Search query" to " " in the app And I press "potato" in the app Then I should see "potato" - And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." \ No newline at end of file + And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." + + @app @3.8.0 + Scenario: Navigate to glossary terms by link (auto-linking) + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "This entry should be automatically linked" in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "This entry should be automatically linked" in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "This entry should be automatically linked" in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I press "Display options" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "admin" + And I press "Side panel" + And I follow "Site administration" + And I follow "Plugins" + And I follow "Manage filters" + And I pause + And I click on "newstate" "select" in the "Glossary auto-linking" "table_row" + And I click on "on" "option" in the "single_select5e32c21f9a4f039" "region" + And I pause + + @app @3.8.0 @OK + Scenario: See comments + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I press "mountain" in the app + Then I should see "Comments (0)" + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + Then I should see "Comments (0)" + And I press "Comments" in the app + And I should see "No comments" + And I press "close" in the app + And I set the field "Add a comment..." to "teacherComment" in the app + And I press "Save comment" in the app + Then I should see "teacherComment" + And I press "close" in the app + And I set the field "Add a comment..." to "teacherComment2" in the app + And I press "Save comment" in the app + Then I should see "teacherComment" + And I should see "teacherComment2" + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + Then I should see "Comments (2)" + And I press "Comments" in the app + And I should see "teacherComment" + And I should see "teacherComment2" \ No newline at end of file From 288612c077f84329cfdbc375c0256b2adc2b6386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 5 Feb 2020 10:53:07 +0100 Subject: [PATCH 054/220] MOBILE-3328 behat: Behat basic test for glossary --- .../tests/behat/app_basic_usage.feature | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index e8c938621..2ad1353f5 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -192,4 +192,46 @@ Feature: Test basic usage of glossary in app Then I should see "Comments (2)" And I press "Comments" in the app And I should see "teacherComment" - And I should see "teacherComment2" \ No newline at end of file + And I should see "teacherComment2" + + @app @3.8.0 @OK + Scenario: Prefetch + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I press "Display options" in the app + And I press "Download" in the app + And I press the back button in the app + And I press the back button in the app + And I press "Course 1" near "Recently accessed courses" in the app + And I switch offline mode to "true" + And I press "Test glossary" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I press "mountain" in the app + Then I should see "mountain" + And I should see "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." + And I should not see "Comments cannot be retrieved" + And I should see "Comments (0)" \ No newline at end of file From 8f10d57c0a437c450f394c2757e731e9cefa7ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 5 Feb 2020 11:50:32 +0100 Subject: [PATCH 055/220] MOBILE-3328 behat: Behat basic test for glossary --- .../tests/behat/app_basic_usage.feature | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index 2ad1353f5..20ac48c83 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -193,7 +193,7 @@ Feature: Test basic usage of glossary in app And I press "Comments" in the app And I should see "teacherComment" And I should see "teacherComment2" - + @app @3.8.0 @OK Scenario: Prefetch When I enter the app @@ -234,4 +234,47 @@ Feature: Test basic usage of glossary in app Then I should see "mountain" And I should see "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." And I should not see "Comments cannot be retrieved" - And I should see "Comments (0)" \ No newline at end of file + And I should see "Comments (0)" + + @app @3.8.0 @OK + Scenario: Sync + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I switch offline mode to "true" + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I should see "Entries to be synced" + And I should see "This Glossary has offline data to be synchronised." + And I switch offline mode to "false" + And I press "close" in the app + And I set the field "Concept" to "testSync" in the app + And I set the field "Definition" to "testSync" in the app + And I press "Save" in the app + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I should see "testSync" + And I should not see "Entries to be synced" + And I should not see "This Glossary has offline data to be synchronised." \ No newline at end of file From e53b8cfe28367751dc456a452115917538fc3168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 6 Feb 2020 10:29:41 +0100 Subject: [PATCH 056/220] MOBILE-3328 behat: Behat basic test for glossary --- .../tests/behat/app_basic_usage.feature | 149 +++++++++++++++++- 1 file changed, 144 insertions(+), 5 deletions(-) diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index 20ac48c83..97b67c995 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -7,8 +7,9 @@ Feature: Test basic usage of glossary in app Background: Given the following "users" exist: | username | firstname | lastname | email | - | teacher1 | Teacher | teacher | teacher1@example.com | - | student1 | Student | student | student1@example.com | + | teacher1 | Teacher | teacher | teacher1@example.com | + | teacher2 | Teacher2 | teacher2 | teacher2@example.com | + | student1 | Student | student | student1@example.com | And the following "courses" exist: | fullname | shortname | category | @@ -17,11 +18,12 @@ Feature: Test basic usage of glossary in app And the following "course enrolments" exist: | user | course | role | | teacher1 | C1 | editingteacher | + | teacher2 | C1 | editingteacher | | student1 | C1 | student | And the following "activities" exist: - | activity | name | intro | course | idnumber | mainglossary | allowcomments | - | glossary | Test glossary | glossary description | C1 | gloss1 | 1 | 1 | + | activity | name | intro | course | idnumber | mainglossary | allowcomments | assessed | scale | + | glossary | Test glossary | glossary description | C1 | gloss1 | 1 | 1 | 1 | 1 | And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | @@ -277,4 +279,141 @@ Feature: Test basic usage of glossary in app And I should see "potato" And I should see "testSync" And I should not see "Entries to be synced" - And I should not see "This Glossary has offline data to be synchronised." \ No newline at end of file + And I should not see "This Glossary has offline data to be synchronised." + + @app @3.8.0 @mobile @OK + Scenario: Add/view ratings (mobile) + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + Then I should see "Average of ratings: -" + And I press "None" in the app + And I press "1" in the app + Then I should see "Average of ratings: 1" + When I enter the app + And I log in as "teacher2" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + And I switch offline mode to "true" + And I press "None" in the app + And I press "0" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "Average of ratings: 1" + And I switch offline mode to "false" + And I press the back button in the app + Then I should see "This Glossary has offline data to be synchronised." + And I press "Display options" in the app + And I press "Synchronise now" in the app + And I press "mountain" in the app + Then I should see "Average of ratings: 0.5" + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + Then the header should be "mountain" in the app + And I should not see "Average of ratings: 0.5" + + @app @3.8.0 @tablet @OK + Scenario: Add/view ratings (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + Then I should see "Average of ratings: -" + And I press "None" in the app + And I press "1" in the app + Then I should see "Average of ratings: 1" + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "teacher2" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + And I switch offline mode to "true" + And I press "None" in the app + And I press "0" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "Average of ratings: 1" + And I switch offline mode to "false" + Then I should see "This Glossary has offline data to be synchronised." + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should see "Average of ratings: 0.5" + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + Then I should not see "Average of ratings: 0.5" \ No newline at end of file From 8f6c39ba2ab6d1176d27b58fcececc08acb4c798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 6 Feb 2020 12:13:04 +0100 Subject: [PATCH 057/220] MOBILE-3295 behat: Behat basic test for forum --- mod/forum/tests/behat/app_basic_usage.feature | 87 +++++++++++++++++-- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 48cea02da..81f08fd83 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -21,8 +21,8 @@ Feature: Test basic usage of forum activity in app | teacher1 | C1 | editingteacher | | teacher2 | C1 | editingteacher | And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | assessed | scale[modgrade_type] | - | forum | Test forum name | Test forum | C1 | forum | 0 | 5 | Point | + | activity | name | intro | course | idnumber | groupmode | assessed | scale | + | forum | Test forum name | Test forum | C1 | forum | 0 | 1 | 1 | @app @3.8.0 @OK Scenario: Student starts a discussion @@ -207,15 +207,15 @@ Feature: Test basic usage of forum activity in app And I press "Auto-test" in the app And I wait "2" seconds And I pause - And I press "Auto-test" near "Information" in the app + And I press "more" in the app And I pause And I should see "Edit" And I pause And I switch offline mode to "true" And I pause - @app @mobile @3.8.0 - Scenario: Add/view ratings + @app @3.8.0 @mobile @OK + Scenario: Add/view ratings (mobile) When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -226,14 +226,83 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app And I press "Auto-test" in the app And I press "Reply" in the app - And I set the field "Write your reply..." to "test" in the app + And I set the field "Write your reply..." to "test2" in the app And I press "Post to forum" in the app When I enter the app - And I log in as "student2" + And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app And I press "Auto-test" in the app - And I pause + And I press "None" near "Auto-test message" in the app + And I press "1" near "Cancel" in the app + And I switch offline mode to "true" + And I press "None" near "test2" in the app + And I press "0" near "Cancel" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "Average of ratings: -" + And I should see "Average of ratings: 1" + And I switch offline mode to "false" + And I press the back button in the app + Then I should see "This Forum has offline data to be synchronised." + And I press "Display options" near "Test forum name" in the app + And I press "Synchronise now" in the app + And I should not see "This Forum has offline data to be synchronised." + And I press "Auto-test" in the app + Then I should see "Average of ratings: 1" + And I should see "Average of ratings: 0" + And I should not see "Average of ratings: -" + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "Auto-test" in the app + Then I should see "Average of ratings: 1" + And I should see "Average of ratings: 0" + And I should not see "Average of ratings: -" + + @app @3.8.0 @tablet @OK + Scenario: Add/view ratings (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test" in the app + And I set the field "Message" to "Auto-test message" in the app + And I press "Post to forum" in the app + And I press "Reply" in the app + And I set the field "Write your reply..." to "test2" in the app + And I press "Post to forum" in the app + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "teacher1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "None" near "Auto-test message" in the app + And I press "1" near "Cancel" in the app + And I switch offline mode to "true" + And I press "None" near "test2" in the app + And I press "0" near "Cancel" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "Average of ratings: -" + And I should see "Average of ratings: 1" + And I switch offline mode to "false" + Then I should see "This Forum has offline data to be synchronised." + And I press "Display options" near "Test forum name" in the app + And I press "Synchronise now" in the app + And I should not see "This Forum has offline data to be synchronised." + Then I should see "Average of ratings: 1" + And I should see "Average of ratings: 0" + And I should not see "Average of ratings: -" + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + Then I should see "Average of ratings: 1" + And I should see "Average of ratings: 0" + And I should not see "Average of ratings: -" @app @3.8.0 @mobile @OK Scenario: Student replies a post offline mobile @@ -438,4 +507,4 @@ Feature: Test basic usage of forum activity in app And I press "Reply" in the app And I set the field "Write your reply" to "ReplyMessage" in the app And I press "Post to forum" in the app - And I pause \ No newline at end of file + And I pauses \ No newline at end of file From ca1cca07f6ae61a343d1460ba1d54a7b2210eb0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Fri, 7 Feb 2020 12:06:44 +0100 Subject: [PATCH 058/220] Fix Display options button --- .../tests/behat/app_basic_usage.feature | 6 ++-- .../tests/behat/app_basic_usage.feature | 8 ++--- .../tests/behat/app_basic_usage.feature | 2 +- mod/forum/tests/behat/app_basic_usage.feature | 29 ++++++++++--------- .../tests/behat/app_basic_usage.feature | 18 ++++++------ .../tests/behat/app_basic_usage.feature | 4 +-- 6 files changed, 34 insertions(+), 33 deletions(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 24ee2e68c..22fd3ec66 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -96,7 +96,7 @@ Feature: Test basic usage of choice activity in app And I switch offline mode to "false" And I press the back button in the app And I press "Test single choice name" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Refresh" in the app Then I should see "Option 1: 0" And I should see "Option 2: 1" @@ -137,7 +137,7 @@ Feature: Test basic usage of choice activity in app When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test single choice name" in the app And I switch offline mode to "true" @@ -180,7 +180,7 @@ Feature: Test basic usage of choice activity in app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app And I press "Choice name" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 7452476e0..a42f3154b 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -397,7 +397,7 @@ Feature: Test basic usage of one course in app Then the header should be "Acceptance test site" in the app And I should see "Course 1" And I press "Course 1" near "Recently accessed courses" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -440,7 +440,7 @@ Feature: Test basic usage of one course in app Then the header should be "Acceptance test site" in the app And I should see "Course 1" And I press "Course 1" near "Recently accessed courses" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -482,7 +482,7 @@ Feature: Test basic usage of one course in app Then the header should be "Acceptance test site" in the app And I should see "Course 1" And I press "Course 1" near "Recently accessed courses" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -533,7 +533,7 @@ Feature: Test basic usage of one course in app Then the header should be "Acceptance test site" in the app And I should see "Course 1" And I press "Course 1" near "Recently accessed courses" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index a22581dec..cf3244604 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -114,7 +114,7 @@ Feature: Test basic usage of courses in app And I should see "Timeline" And I press "Course 1" near "Recently accessed courses" in the app And I press "assignment" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 81f08fd83..ade2e6569 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -105,7 +105,7 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app And I press "Auto-test star" near "Last post a minute ago" in the app Then I should see "Auto-test star message" - And I press "Information" in the app + And I press "Display options" in the app And I press "Star this discussion" in the app And I press the back button in the app And I press "Auto-test star" near "Last post a minute ago" in the app @@ -116,7 +116,7 @@ Feature: Test basic usage of forum activity in app And I press the back button in the app And I press "Auto-test star" near "Last post a minute ago" in the app And I wait "1" seconds - And I press "Information" in the app + And I press "Display options" in the app And I press "Unstar this discussion" in the app And I press the back button in the app And I press "Auto-test star" near "Last post a few seconds ago" in the app @@ -145,12 +145,12 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app And I press "Auto-test star" in the app And I wait "1" seconds - And I press "Information" in the app + And I press "Display options" in the app And I press "Star this discussion" in the app And I press the back button in the app And I press "Auto-test pin" in the app And I wait "1" seconds - And I press "Information" in the app + And I press "Display options" in the app And I press "Pin this discussion" in the app And I press the back button in the app And I should see "Auto-test pin" @@ -159,12 +159,12 @@ Feature: Test basic usage of forum activity in app And I pause And I press "Auto-test pin" in the app And I wait "1" seconds - And I press "Information" in the app + And I press "Display options" in the app And I press "Unpin this discussion" in the app And I press the back button in the app And I press "Auto-test star" in the app And I wait "1" seconds - And I press "Information" in the app + And I press "Display options" in the app And I press "Unstar this discussion" in the app And I press the back button in the app Then I should see "Auto-test star" @@ -183,7 +183,7 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app And I press "Auto-test" in the app And I wait "1" seconds - And I press "Information" in the app + And I press "Display options" in the app Then I should not see "Star this discussion" And I should not see "Pin this discussion" @@ -200,7 +200,8 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app Then I should see "Auto-test" And I press the back button in the app - And I press "Information" in the app + And I pause + And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app And I press "Test forum name" in the app @@ -315,7 +316,7 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app And I press the back button in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app And I press "Test forum name" in the app @@ -346,7 +347,7 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app And I press the back button in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app And I press "Test forum name" in the app @@ -383,7 +384,7 @@ Feature: Test basic usage of forum activity in app And I switch offline mode to "false" And I press the back button in the app And I press "Test forum name" in the app - And I press "Information" in the app + And I press "Display options" near "Test forum name" in the app And I press "Refresh discussions" in the app And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app Then I should see "DiscussionSubject" @@ -426,7 +427,7 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app Then I should see "DiscussionSubject" And I press the back button in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app And I press "Test forum name" in the app @@ -462,7 +463,7 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app Then I should see "DiscussionSubject" And I press the back button in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app And I press "Test forum name" in the app @@ -507,4 +508,4 @@ Feature: Test basic usage of forum activity in app And I press "Reply" in the app And I set the field "Write your reply" to "ReplyMessage" in the app And I press "Post to forum" in the app - And I pauses \ No newline at end of file + And I pause \ No newline at end of file diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index a3450d45b..f887e0f09 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -74,7 +74,7 @@ Feature: Test basic usage of messages in app And I press "Student1 student1" in the app And I set the field "New message" to "heeey student" in the app And I press "Send" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Add to contacts" in the app And I press "Add" in the app When I enter the app @@ -221,7 +221,7 @@ Feature: Test basic usage of messages in app And I press "Student1 student1" in the app And I set the field "New message" to "heeey student" in the app And I press "Send" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Add to contacts" in the app And I press "Add" in the app Then I should see "Contact request sent" @@ -241,10 +241,10 @@ Feature: Test basic usage of messages in app And I press "Send" in the app Then I should see "heeey student" And I should see "hi" - And I press "Information" in the app + And I press "Display options" in the app And I press "Remove from contacts" in the app And I press "Remove" in the app - And I press "Information" in the app + And I press "Display options" in the app Then I should see "Add to contacts" And I press "Delete conversation" in the app And I press "Delete" in the app @@ -446,7 +446,7 @@ Feature: Test basic usage of messages in app Then I should see "Private (2)" And I should see "Starred (1)" And I press "star message" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Star conversation" in the app Then I should see "Private (1)" And I should see "Starred (2)" @@ -627,7 +627,7 @@ Feature: Test basic usage of messages in app And I press "Messages" in the app And I press "Private (1)" in the app And I press "Student2 student2" in the app - And I press "Information" in the app + And I press "Display options" in the app Then I should see "Unmute" And I should not see "Mute" @@ -699,12 +699,12 @@ Feature: Test basic usage of messages in app And I press "Send" in the app And I switch offline mode to "false" And I press "Student1 student1" in the app - And I press "Information" in the app + And I press "Display options" in the app Then I should see "Unstar conversation" And I should see "Show delete messages" And I should see "Delete conversation" And I press "Unstar conversation" in the app - And I press "Information" in the app + And I press "Display options" in the app Then I should see "Star conversation" And I should see "Show delete messages" And I should see "Delete conversation" @@ -715,7 +715,7 @@ Feature: Test basic usage of messages in app And I press "OK" in the app Then I should see "self conversation" And I should not see "self conversation offline" - And I press "Information" in the app + And I press "Display options" in the app And I press "Delete conversation" in the app And I press "Delete" in the app Then I should not see "self conversation" diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index 08fa78a6c..ad2152693 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -567,7 +567,7 @@ Feature: Test basic usage of survey activity in app And I switch offline mode to "false" And I press the back button in the app And I press "Test survey critical incidents" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Refresh" in the app Then I should see "Results" And I should not see "This Survey has offline data to be synchronised." @@ -581,7 +581,7 @@ Feature: Test basic usage of survey activity in app When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app - And I press "Information" in the app + And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test survey critical incidents" in the app And I switch offline mode to "true" From f71454504eda8d1a289f2767259311a2e68416f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 10 Feb 2020 09:25:08 +0100 Subject: [PATCH 059/220] MOBILE-3295 behat: Behat basic test for forum --- mod/forum/tests/behat/app_basic_usage.feature | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index ade2e6569..b7737e7de 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -38,7 +38,6 @@ Feature: Test basic usage of forum activity in app And I press "My happy subject" in the app And I should see "An awesome message" - @app_upto3.6.1 Scenario: Student posts a reply When I enter the app @@ -187,8 +186,7 @@ Feature: Test basic usage of forum activity in app Then I should not see "Star this discussion" And I should not see "Pin this discussion" - - @app @mobile @3.8.0 + @app @3.8.0 @OK Scenario: Edit a forum post (only online) When I enter the app And I log in as "student1" @@ -200,20 +198,21 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app Then I should see "Auto-test" And I press the back button in the app - And I pause And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app And I press "Test forum name" in the app - And I press "Auto-test" in the app - And I wait "2" seconds - And I pause - And I press "more" in the app - And I pause - And I should see "Edit" - And I pause + And I press "Auto-test" near "Sort by last post creation date in descending order" in the app + And I press "Display options" near "Reply" in the app + Then I should see "Edit" + And I press "Edit" in the app + And I set the field "Write your reply..." to "Auto-test message edited" in the app + And I press "Save changes" And I switch offline mode to "true" - And I pause + And I press "Display options" near "Reply" in the app + Then I should see "There was a problem connecting to the site. Please check your connection and try again." + And I press "OK" in the app + And I should not see "Edit" @app @3.8.0 @mobile @OK Scenario: Add/view ratings (mobile) @@ -449,7 +448,6 @@ Feature: Test basic usage of forum activity in app And I should see "DiscussionMessage" And I should not see "There was a problem connecting to the site. Please check your connection and try again." - @app @3.8.0 @tablet @OK Scenario: Prefetch tablet When I enter the app From 298dc89c06eae395907ec1779fd319e3a539ef4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 10 Feb 2020 09:49:39 +0100 Subject: [PATCH 060/220] MOBILE-3295 behat: Behat basic test for forum --- mod/forum/tests/behat/app_basic_usage.feature | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index b7737e7de..2ff80e1ec 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -214,6 +214,38 @@ Feature: Test basic usage of forum activity in app And I press "OK" in the app And I should not see "Edit" + @app @3.8.0 @OK + Scenario: Delete a forum post (only online) + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test" in the app + And I set the field "Message" to "Auto-test message" in the app + And I press "Post to forum" in the app + Then I should see "Auto-test" + And I press the back button in the app + And I press "Display options" in the app + And I press "Show download options" in the app + And I press "cloud download" near "Test forum name" in the app + And I press "Test forum name" in the app + And I press "Auto-test" near "Sort by last post creation date in descending order" in the app + And I press "Display options" near "Reply" in the app + Then I should see "Delete" + And I press "Delete" in the app + And I press "Cancel" in the app + And I switch offline mode to "true" + And I press "Display options" near "Reply" in the app + Then I should see "There was a problem connecting to the site. Please check your connection and try again." + And I press "OK" in the app + And I should not see "Delete" + And I switch offline mode to "false" + And I press "Display options" near "Reply" in the app + And I press "Delete" in the app + And I press "Delete" in the app + Then I should not see "Auto-test" + @app @3.8.0 @mobile @OK Scenario: Add/view ratings (mobile) When I enter the app From e4a87e06fb0740a4a7616e9223bec451c8f9b16e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 10 Feb 2020 10:48:44 +0100 Subject: [PATCH 061/220] MOBILE-3295 behat: Behat basic test for forum --- mod/forum/tests/behat/app_basic_usage.feature | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 2ff80e1ec..cf78898f2 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -186,6 +186,63 @@ Feature: Test basic usage of forum activity in app Then I should not see "Star this discussion" And I should not see "Pin this discussion" + @app @3.8.0 @mobile @OK + Scenario: Edit a not sent reply offline (mobile) + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test" in the app + And I set the field "Message" to "Auto-test message" in the app + And I press "Post to forum" in the app + And I press "Auto-test" near "Sort by last post creation date in descending order" in the app + And I switch offline mode to "true" + And I press "Reply" in the app + And I set the field "Write your reply..." to "not sent reply" in the app + And I press "Post to forum" in the app + And I press "Display options" near "not sent reply" in the app + Then I should see "Edit" + And I press "Edit" in the app + And I set the field "Write your reply..." to "not sent reply edited" in the app + And I press "Post to forum" in the app + Then I should see "Not sent" + And I should see "This Discussion has offline data to be synchronised" + And I switch offline mode to "false" + And I press the back button in the app + And I press "Auto-test" near "Sort by last post creation date in descending order" in the app + Then I should not see "Not sent" + And I should not see "This Discussion has offline data to be synchronised" + + @app @3.8.0 @tablet @OK + Scenario: Edit a not sent reply offline (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test" in the app + And I set the field "Message" to "Auto-test message" in the app + And I press "Post to forum" in the app + And I press "Auto-test" near "Sort by last post creation date in descending order" in the app + And I switch offline mode to "true" + And I press "Reply" in the app + And I set the field "Write your reply..." to "not sent reply" in the app + And I press "Post to forum" in the app + And I press "Display options" near "not sent reply" in the app + Then I should see "Edit" + And I press "Edit" in the app + And I set the field "Write your reply..." to "not sent reply edited" in the app + And I press "Post to forum" in the app + Then I should see "Not sent" + And I should see "This Discussion has offline data to be synchronised" + And I switch offline mode to "false" + And I press the back button in the app + And I press "Test forum name" in the app + Then I should not see "Not sent" + And I should not see "This Discussion has offline data to be synchronised" + @app @3.8.0 @OK Scenario: Edit a forum post (only online) When I enter the app From 626786a47112375cdca7bb2b4550d90eea400976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 10 Feb 2020 11:22:12 +0100 Subject: [PATCH 062/220] MOBILE-3295 behat: Behat basic test for forum --- mod/forum/tests/behat/app_basic_usage.feature | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index cf78898f2..56a160db8 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -243,6 +243,28 @@ Feature: Test basic usage of forum activity in app Then I should not see "Not sent" And I should not see "This Discussion has offline data to be synchronised" + @app @3.8.0 @OK + Scenario: Edit a not sent new discussion offline + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I switch offline mode to "true" + And I press "close" in the app + And I set the field "Subject" to "Auto-test" in the app + And I set the field "Message" to "Auto-test message" in the app + And I press "Post to forum" in the app + And I press "Auto-test" in the app + And I set the field "Message" to "Auto-test message edited" in the app + And I press "Post to forum" in the app + Then I should see "This Forum has offline data to be synchronised." + And I switch offline mode to "false" + And I press "Auto-test" in the app + And I press "Post to forum" in the app + Then I should not see "This Forum has offline data to be synchronised." + And I press "Auto-test" near "Sort by last post creation date in descending order" in the app + And I should see "Auto-test message edited" + @app @3.8.0 @OK Scenario: Edit a forum post (only online) When I enter the app @@ -264,7 +286,7 @@ Feature: Test basic usage of forum activity in app Then I should see "Edit" And I press "Edit" in the app And I set the field "Write your reply..." to "Auto-test message edited" in the app - And I press "Save changes" + And I press "Save changes" in the app And I switch offline mode to "true" And I press "Display options" near "Reply" in the app Then I should see "There was a problem connecting to the site. Please check your connection and try again." @@ -302,7 +324,7 @@ Feature: Test basic usage of forum activity in app And I press "Delete" in the app And I press "Delete" in the app Then I should not see "Auto-test" - + @app @3.8.0 @mobile @OK Scenario: Add/view ratings (mobile) When I enter the app From 4108ea15d872114a3ee2d8b71c2671f8dec96de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Tue, 11 Feb 2020 10:04:36 +0100 Subject: [PATCH 063/220] MOBILE-3295 behat: Behat basic test for forum --- mod/forum/tests/behat/app_basic_usage.feature | 107 ++++++++---------- 1 file changed, 49 insertions(+), 58 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 56a160db8..af3f0f42c 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -24,8 +24,8 @@ Feature: Test basic usage of forum activity in app | activity | name | intro | course | idnumber | groupmode | assessed | scale | | forum | Test forum name | Test forum | C1 | forum | 0 | 1 | 1 | - @app @3.8.0 @OK - Scenario: Student starts a discussion + @app @3.8.0 @OK + Scenario: Student starts a discussion When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -38,8 +38,8 @@ Feature: Test basic usage of forum activity in app And I press "My happy subject" in the app And I should see "An awesome message" - @app_upto3.6.1 - Scenario: Student posts a reply + @app_upto3.6.1 + Scenario: Student posts a reply When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -55,8 +55,8 @@ Feature: Test basic usage of forum activity in app Then I should see "DiscussionMessage" And I should see "ReplyMessage" - @app_from3.7 - Scenario: Student posts a reply + @app_from3.7 + Scenario: Student posts a reply When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -72,7 +72,7 @@ Feature: Test basic usage of forum activity in app Then I should see "DiscussionMessage" And I should see "ReplyMessage" - Scenario: Test that 'open in browser' works for forum + Scenario: Test that 'open in browser' works for forum When I enter the app And I change viewport size to "360x640" And I log in as "student1" @@ -87,8 +87,8 @@ Feature: Test basic usage of forum activity in app And I close the browser tab opened by the app And I press the back button in the app - @app @mobile @3.8.0 - Scenario: Student stars a discussion + @app @3.8.0 @mobile @OK + Scenario: Student stars a discussion (mobile) When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -104,27 +104,55 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app And I press "Auto-test star" near "Last post a minute ago" in the app Then I should see "Auto-test star message" - And I press "Display options" in the app - And I press "Star this discussion" in the app And I press the back button in the app + And I press "Display options" near "Last post a minute ago" in the app + And I press "Star this discussion" in the app And I press "Auto-test star" near "Last post a minute ago" in the app Then I should see "Auto-test star message" And I press the back button in the app And I press "Auto-test star" near "Last post a few seconds ago" in the app Then I should see "Auto-test no star message" And I press the back button in the app - And I press "Auto-test star" near "Last post a minute ago" in the app - And I wait "1" seconds - And I press "Display options" in the app + And I press "Display options" near "Last post a minute ago" in the app And I press "Unstar this discussion" in the app - And I press the back button in the app And I press "Auto-test star" near "Last post a few seconds ago" in the app Then I should see "Auto-test no star message" And I press the back button in the app And I press "Auto-test star" near "Last post a minute ago" in the app Then I should see "Auto-test star message" - @app @mobile @3.8.0 + @app @3.8.0 @tablet @OK + Scenario: Student stars a discussion (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum name" in the app + And I press "close" in the app + And I set the field "Subject" to "Auto-test star" in the app + And I set the field "Message" to "Auto-test star message" in the app + And I press "Post to forum" in the app + And I wait "60" seconds + And I press "close" in the app + And I set the field "Subject" to "Auto-test star" in the app + And I set the field "Message" to "Auto-test no star message" in the app + And I press "Post to forum" in the app + And I press "Auto-test star" near "Last post a minute ago" in the app + Then I should see "Auto-test star message" + And I press "Display options" near "Last post a minute ago" in the app + And I press "Star this discussion" in the app + And I press "Auto-test star" near "Last post a minute ago" in the app + Then I should see "Auto-test star message" + And I press "Auto-test star" near "Last post a few seconds ago" in the app + Then I should see "Auto-test no star message" + And I press "Display options" near "Last post a minute ago" in the app + And I press "Unstar this discussion" in the app + And I press "Auto-test star" near "Last post a few seconds ago" in the app + Then I should see "Auto-test no star message" + And I press "Auto-test star" near "Last post a minute ago" in the app + Then I should see "Auto-test star message" + + @app @3.8.0 @OK Scenario: Teacher star and pin a discussion When I enter the app And I log in as "teacher1" @@ -142,33 +170,19 @@ Feature: Test basic usage of forum activity in app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app - And I press "Auto-test star" in the app - And I wait "1" seconds - And I press "Display options" in the app + And I press "Display options" near "Auto-test star" in the app And I press "Star this discussion" in the app - And I press the back button in the app - And I press "Auto-test pin" in the app - And I wait "1" seconds - And I press "Display options" in the app + And I press "Display options" near "Auto-test pin" in the app And I press "Pin this discussion" in the app - And I press the back button in the app And I should see "Auto-test pin" And I should see "Auto-test star" And I should see "Auto-test" - And I pause - And I press "Auto-test pin" in the app - And I wait "1" seconds - And I press "Display options" in the app + And I press "Display options" near "Auto-test pin" in the app And I press "Unpin this discussion" in the app - And I press the back button in the app - And I press "Auto-test star" in the app - And I wait "1" seconds - And I press "Display options" in the app + And I press "Display options" near "Auto-test star" in the app And I press "Unstar this discussion" in the app - And I press the back button in the app Then I should see "Auto-test star" And I should see "Auto-test pin" - And I pause @app @mobile @3.6 @OK Scenario: Teacher checks pin and star in 3.6 @@ -594,27 +608,4 @@ Feature: Test basic usage of forum activity in app And I press the back button in the app And I switch offline mode to "false" And I press "refresh" near "Test forum name" in the app - Then I should not see "There was a problem connecting to the site. Please check your connection and try again." - - @app @3.8.0 - Scenario: Student sorts a forum discussion - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app - And I set the field "Subject" to "DiscussionSubject" in the app - And I set the field "Message" to "DiscussionMessage" in the app - And I press "Post to forum" in the app - Then I should see "DiscussionSubject" - And I press "Add a new discussion topic" in the app - And I set the field "Subject" to "DiscussionSubject more replies" in the app - And I set the field "Message" to "DiscussionMessage more replies" in the app - And I press "Post to forum" in the app - Then I should see "DiscussionSubject" - And I should see "DiscussionSubject more replies" - And I press "DiscussionSubject more replies" in the app - And I press "Reply" in the app - And I set the field "Write your reply" to "ReplyMessage" in the app - And I press "Post to forum" in the app - And I pause \ No newline at end of file + Then I should not see "There was a problem connecting to the site. Please check your connection and try again." \ No newline at end of file From 7d8074cccac73f9c21bf0faf6caadb71d74c5a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 12 Feb 2020 09:06:31 +0100 Subject: [PATCH 064/220] MOBILE-3295 MOBILE-3297 behat: Improvement on forum and survey behat --- mod/forum/tests/behat/app_basic_usage.feature | 37 +------------------ .../tests/behat/app_basic_usage.feature | 6 +-- 2 files changed, 3 insertions(+), 40 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index af3f0f42c..d913a45a0 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -38,23 +38,6 @@ Feature: Test basic usage of forum activity in app And I press "My happy subject" in the app And I should see "An awesome message" - @app_upto3.6.1 - Scenario: Student posts a reply - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app - And I set the field "Subject" to "DiscussionSubject" in the app - And I set the field "Message" to "DiscussionMessage" in the app - And I press "Post to forum" in the app - And I press "DiscussionSubject" in the app - And I press "Reply" in the app - And I set the field "Message" to "ReplyMessage" in the app - And I press "Post to forum" in the app - Then I should see "DiscussionMessage" - And I should see "ReplyMessage" - @app_from3.7 Scenario: Student posts a reply When I enter the app @@ -72,21 +55,6 @@ Feature: Test basic usage of forum activity in app Then I should see "DiscussionMessage" And I should see "ReplyMessage" - Scenario: Test that 'open in browser' works for forum - When I enter the app - And I change viewport size to "360x640" - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - And I press the page menu button in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "Test forum name" - And I should see "Add a new discussion topic" - And I close the browser tab opened by the app - And I press the back button in the app - @app @3.8.0 @mobile @OK Scenario: Student stars a discussion (mobile) When I enter the app @@ -184,7 +152,7 @@ Feature: Test basic usage of forum activity in app Then I should see "Auto-test star" And I should see "Auto-test pin" - @app @mobile @3.6 @OK + @app_upto3.6.0 @OK Scenario: Teacher checks pin and star in 3.6 When I enter the app And I log in as "teacher1" @@ -195,8 +163,7 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app And I press "Auto-test" in the app - And I wait "1" seconds - And I press "Display options" in the app + And I press "Information" in the app Then I should not see "Star this discussion" And I should not see "Pin this discussion" diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index ad2152693..12aeb3487 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -242,7 +242,6 @@ Feature: Test basic usage of survey activity in app Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." And I should see "1 people have completed this survey so far" - @app @3.8.0 @mobile @OK Scenario: Student answers a survey of Colles (preferred) and see results mobile Given the following "activities" exist: @@ -252,7 +251,6 @@ Feature: Test basic usage of survey activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test survey Colles (preferred)" in the app - And I pause And I press "Choose" near "1. my learning focuses on issues that interest me." in the app And I press "Sometimes" near "Often" in the app And I press "Choose" near "2. what I learn is important for my professional practice." in the app @@ -313,7 +311,6 @@ Feature: Test basic usage of survey activity in app Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." And I should see "1 people have completed this survey so far" - @app @3.8.0 @tablet @OK Scenario: Student answers a survey of Colles (preferred) and see results tablet Given the following "activities" exist: @@ -549,8 +546,7 @@ Feature: Test basic usage of survey activity in app And I log in as "student1" Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." And I should see "1 people have completed this survey so far" - - + @app @3.8.0 @OK Scenario: Student answers a survey offline and sync survey Given the following "activities" exist: From 34c947f90e34bc30526f5555f873911bcb94ad9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 12 Feb 2020 10:09:38 +0100 Subject: [PATCH 065/220] MOBILE-3328 behat: Improvement on glossary behat --- .../tests/behat/app_basic_usage.feature | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index 97b67c995..43e8ec9bd 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -95,47 +95,6 @@ Feature: Test basic usage of glossary in app Then I should see "potato" And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." - @app @3.8.0 - Scenario: Navigate to glossary terms by link (auto-linking) - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "This entry should be automatically linked" in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "This entry should be automatically linked" in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "This entry should be automatically linked" in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I press "Display options" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "admin" - And I press "Side panel" - And I follow "Site administration" - And I follow "Plugins" - And I follow "Manage filters" - And I pause - And I click on "newstate" "select" in the "Glossary auto-linking" "table_row" - And I click on "on" "option" in the "single_select5e32c21f9a4f039" "region" - And I pause - @app @3.8.0 @OK Scenario: See comments When I enter the app From 63b7c6219812e0372b61655b22a836c32c26025a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 12 Feb 2020 12:07:35 +0100 Subject: [PATCH 066/220] MOBILE-3342 behat: Behat basic test for comments --- .../tests/behat/app_basic_usage.feature | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100755 mod/comments/tests/behat/app_basic_usage.feature diff --git a/mod/comments/tests/behat/app_basic_usage.feature b/mod/comments/tests/behat/app_basic_usage.feature new file mode 100755 index 000000000..6b7ae1e64 --- /dev/null +++ b/mod/comments/tests/behat/app_basic_usage.feature @@ -0,0 +1,155 @@ +@mod @mod_comments @app @javascript +Feature: Test basic usage of comments in app + In order to participate in the comments while using the mobile app + As a student + I need basic comments functionality to work + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student | student | student1@example.com | + + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | mainglossary | allowcomments | assessed | scale | + | glossary | Test glossary | glossary description | C1 | gloss1 | 1 | 1 | 1 | 1 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | comments | + | data | Data | Data info | C1 | data1 | 1 | + + + @app @3.8.0 @OK + Scenario: Add comments and delete comments (database) + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Data" in the app + And I press "Display options" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I add a "Text input" field to "Data" database and I fill the form with: + | Field name | Test field name | + | Field description | Test field description | + And I press "Save" + And I close the browser tab opened by the app + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Data" in the app + And I press "add" in the app + And I set the field "Test field name" to "Test" in the app + And I press "Save" in the app + And I press "More" in the app + And I press "Comments (0)" in the app + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Comment created" + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Data" in the app + And I press "More" in the app + And I press "Comments (1)" in the app + And I press "close" in the app + And I set the field "Add a comment..." to "comment test student" in the app + And I press "Save comment" in the app + Then I should see "Comment created" + And I should see "comment test" + And I should see "comment test student" + And I press the back button in the app + And I should see "Comments (2)" + And I press "Comments (2)" in the app + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should see "comment test" + And I should not see "comment test student" + And I press the back button in the app + And I should see "Comments (1)" + + @app @3.8.0 @OK + Scenario: Add comments offline, delete comments offline and sync (database) + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Data" in the app + And I press "Display options" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I add a "Text input" field to "Data" database and I fill the form with: + | Field name | Test field name | + | Field description | Test field description | + And I press "Save" + And I close the browser tab opened by the app + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Data" in the app + And I press "add" in the app + And I set the field "Test field name" to "Test" in the app + And I press "Save" in the app + And I press "More" in the app + And I press "Comments (0)" in the app + And I switch offline mode to "true" + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "There are offline comments to be synchronised." + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (0)" + And I press "Comments (0)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should not see "There are offline comments to be synchronised." + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + And I press "Comments (1)" in the app + And I switch offline mode to "true" + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should see "There are offline comments to be synchronised." + And I should see "Deleted offline" + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + And I press "Comments (1)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should not see "There are offline comments to be synchronised." + And I should not see "comment test" + And I press the back button in the app + And I should see "Comments (0)" \ No newline at end of file From 039e9d6e10f26e4566fe3bf9cf20a109cf7e7508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 13 Feb 2020 10:53:27 +0100 Subject: [PATCH 067/220] MOBILE-3342 behat: Behat basic test for comments --- .../tests/behat/app_basic_usage.feature | 342 ++++++++++++++++++ 1 file changed, 342 insertions(+) diff --git a/mod/comments/tests/behat/app_basic_usage.feature b/mod/comments/tests/behat/app_basic_usage.feature index 6b7ae1e64..1971374f4 100755 --- a/mod/comments/tests/behat/app_basic_usage.feature +++ b/mod/comments/tests/behat/app_basic_usage.feature @@ -152,4 +152,346 @@ Feature: Test basic usage of comments in app Then I should not see "There are offline comments to be synchronised." And I should not see "comment test" And I press the back button in the app + And I should see "Comments (0)" + + @app @3.8.0 @OK + Scenario: Add comments and delete comments (glossary) + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "potato" in the app + And I press "Comments (0)" in the app + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Comment created" + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "potato" in the app + And I press "Comments (1)" in the app + And I press "close" in the app + And I set the field "Add a comment..." to "comment test student" in the app + And I press "Save comment" in the app + Then I should see "Comment created" + And I should see "comment test" + And I should see "comment test student" + And I press the back button in the app + And I should see "Comments (2)" + And I press "Comments (2)" in the app + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should see "comment test" + And I should not see "comment test student" + And I press the back button in the app + And I should see "Comments (1)" + + @app @3.8.0 @OK + Scenario: Add comments offline, delete comments offline and sync (glossary) + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "potato" in the app + And I press "Comments (0)" in the app + And I switch offline mode to "true" + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "There are offline comments to be synchronised." + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (0)" + And I press "Comments (0)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should not see "There are offline comments to be synchronised." + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + And I press "Comments (1)" in the app + And I switch offline mode to "true" + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should see "There are offline comments to be synchronised." + And I should see "Deleted offline" + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + And I press "Comments (1)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should not see "There are offline comments to be synchronised." + And I should not see "comment test" + And I press the back button in the app + And I should see "Comments (0)" + + @app @3.8.0 @mobile @OK + Scenario: Add comments and delete comments mobile (blogs) + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "menu" in the app + And I press "Website" in the app + And I switch to the browser tab opened by the app + And I follow "Log in" + And I log in as "teacher1" + And I click on "Side panel" "button" + And I follow "C1" + And I press "Actions menu" + And I follow "Turn editing on" + And I click on "Side panel" "button" + And I follow "Add a block" + And I follow "Blog menu" + And I follow "Add an entry about this course" + And I set the field "Entry title" to "Blog test" + And I set the field "Blog entry body" to "Blog body" + And I press "Save changes" + And I close the browser tab opened by the app + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "menu" in the app + And I press "Site blog" in the app + Then I should see "Blog test" + And I should see "Blog body" + And I should see "Comments (0)" + And I press "Comments (0)" in the app + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Comment created" + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + And I press "Comments (1)" in the app + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should not see "comment test" + And I press the back button in the app + And I should see "Comments (0)" + + @app @3.8.0 @tablet @OK + Scenario: Add comments and delete comments tablet (blogs) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "menu" in the app + And I press "Website" in the app + And I switch to the browser tab opened by the app + And I follow "Log in" + And I log in as "teacher1" + And I follow "C1" + And I press "Actions menu" + And I follow "Turn editing on" + And I follow "Add a block" + And I follow "Blog menu" + And I follow "Add an entry about this course" + And I set the field "Entry title" to "Blog test" + And I set the field "Blog entry body" to "Blog body" + And I press "Save changes" + And I close the browser tab opened by the app + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Site blog" in the app + Then I should see "Blog test" + And I should see "Blog body" + And I should see "Comments (0)" + And I press "Comments (0)" in the app + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Comment created" + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + And I press "Comments (1)" in the app + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should not see "comment test" + And I press the back button in the app + And I should see "Comments (0)" + + @app @3.8.0 @mobile @OK + Scenario: Add comments offline, delete comments offline and sync mobile (blogs) + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "menu" in the app + And I press "Website" in the app + And I switch to the browser tab opened by the app + And I follow "Log in" + And I log in as "teacher1" + And I click on "Side panel" "button" + And I follow "C1" + And I press "Actions menu" + And I follow "Turn editing on" + And I click on "Side panel" "button" + And I follow "Add a block" + And I follow "Blog menu" + And I follow "Add an entry about this course" + And I set the field "Entry title" to "Blog test" + And I set the field "Blog entry body" to "Blog body" + And I press "Save changes" + And I close the browser tab opened by the app + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "menu" in the app + And I press "Site blog" in the app + Then I should see "Blog test" + And I should see "Blog body" + And I should see "Comments (0)" + And I press "Comments (0)" in the app + And I switch offline mode to "true" + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "There are offline comments to be synchronised." + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (0)" + And I press "Comments (0)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should not see "There are offline comments to be synchronised." + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + And I press "Comments (1)" in the app + And I switch offline mode to "true" + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should see "There are offline comments to be synchronised." + And I should see "Deleted offline" + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + And I press "Comments (1)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should not see "There are offline comments to be synchronised." + And I should not see "comment test" + And I press the back button in the app + And I should see "Comments (0)" + + @app @3.8.0 @tablet @OK + Scenario: Add comments offline, delete comments offline and sync tablet (blogs) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "menu" in the app + And I press "Website" in the app + And I switch to the browser tab opened by the app + And I follow "Log in" + And I log in as "teacher1" + And I follow "C1" + And I press "Actions menu" + And I follow "Turn editing on" + And I follow "Add a block" + And I follow "Blog menu" + And I follow "Add an entry about this course" + And I set the field "Entry title" to "Blog test" + And I set the field "Blog entry body" to "Blog body" + And I press "Save changes" + And I close the browser tab opened by the app + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Site blog" in the app + Then I should see "Blog test" + And I should see "Blog body" + And I should see "Comments (0)" + And I press "Comments (0)" in the app + And I switch offline mode to "true" + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "There are offline comments to be synchronised." + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (0)" + And I press "Comments (0)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should not see "There are offline comments to be synchronised." + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + And I press "Comments (1)" in the app + And I switch offline mode to "true" + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should see "There are offline comments to be synchronised." + And I should see "Deleted offline" + And I should see "comment test" + And I press the back button in the app + And I should see "Comments (1)" + And I press "Comments (1)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should not see "There are offline comments to be synchronised." + And I should not see "comment test" + And I press the back button in the app And I should see "Comments (0)" \ No newline at end of file From 31c8a79d0f3851d2b34b9352b1368d38180e8e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 13 Feb 2020 12:11:25 +0100 Subject: [PATCH 068/220] MOBILE-3328 behat: Behat basic test for glossary --- .../tests/behat/app_basic_usage.feature | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index 43e8ec9bd..285b878bb 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -95,6 +95,50 @@ Feature: Test basic usage of glossary in app Then I should see "potato" And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." + @app @3.8.0 @OK + Scenario: Navigate to glossary terms by link (auto-linking) + And the "glossary" filter is "on" + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "This entry should be automatically linked" in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "This entry should be automatically linked" in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "This entry should be automatically linked" in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I press the back button in the app + And I press "Test forum name" in the app + And I press "add" in the app + And I set the field "Subject" to "Testing auto-link glossary" + And I set the field "Message" to "Glossary terms auto-linked: potato car mountain" in the app + And I press "Post to forum" in the app + And I press "Testing auto-link glossary" near "Last post a few seconds ago" in the app + And I press "car" in the app + Then the header should be "car" in the app + And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." + And I press the back button in the app + And I press "mountain" in the app + Then the header should be "mountain" in the app + And I should see "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." + @app @3.8.0 @OK Scenario: See comments When I enter the app From bb9f2eb1cd69206f9a0a8beed5043d9239fa564c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Tue, 18 Feb 2020 10:18:56 +0100 Subject: [PATCH 069/220] MOBILE-3352 behat: Behat basic test for assignment --- .../tests/behat/app_basic_usage.feature | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 mod/assignment/tests/behat/app_basic_usage.feature diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature new file mode 100755 index 000000000..73ff1988b --- /dev/null +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -0,0 +1,63 @@ +@mod @mod_assign @app @javascript +Feature: Test basic usage of assignment activity in app + In order to participate in the assignment while using the mobile app + I need basic assignment functionality to work + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student | student | student1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + And the following "activities" exist: + | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | duedate | + | assign | C1 | assign1 | assignment1 | Test assignment description1 | 1 | 1 | + + + @app @3.8.0 @OK + Scenario: View assign and add a submission (online text), view own submission or student submission and view list of student submissions (as teacher) + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "assignment1" in the app + Then the header should be "assignment1" in the app + And I should see "Test assignment description1" + And I should see "Due date" + And I should see "Thursday, 1 January 1970, 1:00 AM" + And I press "Add submission" in the app + And I set the field "Online text submissions" to "Submission test" in the app + And I press "Save" in the app + Then I should see "Draft (not submitted)" + And I should see "Not graded" + And I press "Edit submission" in the app + And I set the field "Online text submissions" to "Submission test edited" in the app + And I press "Save" in the app + And I press "OK" in the app + And I press "Submit assignment" in the app + And I press "OK" in the app + Then I should see "Submitted for grading" + And I should see "Not graded" + And I should see "Submission test edited" + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "assignment1" in the app + Then the header should be "assignment1" in the app + And I press "Submitted" in the app + Then I should see "Student student" + And I should see "Not graded" + And I press "Student student" near "assignment1" in the app + Then I should see "Online text submission" + And I should see "Submission test edited" \ No newline at end of file From 9f3160f9700e827b97ade948267f52bb7720d8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 20 Feb 2020 09:23:51 +0100 Subject: [PATCH 070/220] MOBILE-3352 behat: Behat basic test for assignment --- .../tests/behat/app_basic_usage.feature | 79 ++++++++++++++++++- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index 73ff1988b..a858bb185 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -16,12 +16,12 @@ Feature: Test basic usage of assignment activity in app | teacher1 | C1 | editingteacher | | student1 | C1 | student | And the following "activities" exist: - | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | duedate | - | assign | C1 | assign1 | assignment1 | Test assignment description1 | 1 | 1 | + | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | duedate | attemptreopenmethod | + | assign | C1 | assign1 | assignment1 | Test assignment description1 | 1 | 1 | manual | @app @3.8.0 @OK - Scenario: View assign and add a submission (online text), view own submission or student submission and view list of student submissions (as teacher) + Scenario: View assign and add a submission (online text), submit for grading, view own submission or student submission and view list of student submissions (as teacher) When I enter the app And I log in as "student1" Then the header should be "Acceptance test site" in the app @@ -60,4 +60,75 @@ Feature: Test basic usage of assignment activity in app And I should see "Not graded" And I press "Student student" near "assignment1" in the app Then I should see "Online text submission" - And I should see "Submission test edited" \ No newline at end of file + And I should see "Submission test edited" + + @app @3.8.0 @OK + Scenario: Add new attempt from previous submission + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "assignment1" in the app + Then the header should be "assignment1" in the app + And I should see "Test assignment description1" + And I should see "Due date" + And I should see "Thursday, 1 January 1970, 1:00 AM" + And I press "Add submission" in the app + And I set the field "Online text submissions" to "Submission test" in the app + And I press "Save" in the app + And I press "Submit assignment" in the app + And I press "OK" in the app + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "assignment1" in the app + Then the header should be "assignment1" in the app + And I press "Participants" in the app + Then I should see "Student student" + And I should see "Not graded" + And I press "Student student" near "assignment1" in the app + Then I should see "Online text submission" + And I should see "Submission test" + And I press "Grade" in the app + And I press "Allow another attempt" in the app + And I press "Done" + Then I should see "Reopened" + And I should see "Not graded" + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "assignment1" in the app + And I should see "Reopened" + And I should see "2 out of Unlimited" + And I should see "Add a new attempt based on previous submission" + And I should see "Add a new attempt" + And I press "Add a new attempt based on previous submission" in the app + And I press "OK" in the app + Then I should see "Submission test" + And I set the field "Online text submissions" to "Submission test 2 attempt" in the app + And I press "Save" in the app + And I press "OK" in the app + And I press "Submit assignment" in the app + And I press "OK" in the app + When I enter the app + And I log in as "teacher1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "assignment1" in the app + Then the header should be "assignment1" in the app + And I press "Participants" in the app + Then I should see "Student student" + And I should see "Not graded" + And I press "Student student" near "assignment1" in the app + Then I should see "Online text submission" + And I should see "Submission test 2 attempt" \ No newline at end of file From a9e0677dbd8c0290e3ab5d9da5ee9073bd290df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 20 Feb 2020 09:51:56 +0100 Subject: [PATCH 071/220] MOBILE-3352 behat: Behat basic test for assignment --- .../tests/behat/app_basic_usage.feature | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index a858bb185..ca6a5f23a 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -131,4 +131,30 @@ Feature: Test basic usage of assignment activity in app And I should see "Not graded" And I press "Student student" near "assignment1" in the app Then I should see "Online text submission" - And I should see "Submission test 2 attempt" \ No newline at end of file + And I should see "Submission test 2 attempt" + + @app @3.8.0 @OK + Scenario: Add submission offline (online text) + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "assignment1" in the app + Then the header should be "assignment1" in the app + And I should see "Test assignment description1" + And I should see "Due date" + And I should see "Thursday, 1 January 1970, 1:00 AM" + And I press "Add submission" in the app + And I switch offline mode to "true" + And I set the field "Online text submissions" to "Submission test" in the app + And I press "Save" in the app + And I press "Submit assignment" in the app + And I press "OK" in the app + Then I should see "This Assignment has offline data to be synchronised." + And I switch offline mode to "false" + And I press the back button in the app + And I press "assignment1" in the app + Then I should not see "This Assignment has offline data to be synchronised." + And I should see "Submitted for grading" \ No newline at end of file From 0b8fc262ba0815c97c2db4f666be152fd25403b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 20 Feb 2020 10:19:44 +0100 Subject: [PATCH 072/220] MOBILE-3352 behat: Behat basic test for assignment --- .../tests/behat/app_basic_usage.feature | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index ca6a5f23a..8bc5c0a1d 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -157,4 +157,39 @@ Feature: Test basic usage of assignment activity in app And I press the back button in the app And I press "assignment1" in the app Then I should not see "This Assignment has offline data to be synchronised." - And I should see "Submitted for grading" \ No newline at end of file + And I should see "Submitted for grading" + + @app @3.8.0 @OK + Scenario: Edit an offline submission before synchronizing it + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "assignment1" in the app + Then the header should be "assignment1" in the app + And I should see "Test assignment description1" + And I should see "Due date" + And I should see "Thursday, 1 January 1970, 1:00 AM" + And I press "Add submission" in the app + And I switch offline mode to "true" + And I set the field "Online text submissions" to "Submission test1" in the app + And I press "Save" in the app + Then I should see "This Assignment has offline data to be synchronised." + And I should see "Submission test1" + And I press "Edit submission" in the app + And I set the field "Online text submissions" to "Submission test edited offline" in the app + And I press "Save" in the app + Then I should see "This Assignment has offline data to be synchronised." + And I should not see "Submission test1" + And I should see "Submission test edited offline" + And I press "Submit assignment" in the app + And I press "OK" in the app + Then I should see "This Assignment has offline data to be synchronised." + And I switch offline mode to "false" + And I press the back button in the app + And I press "assignment1" in the app + Then I should not see "This Assignment has offline data to be synchronised." + And I should see "Submitted for grading" + And I should see "Submission test edited offline" \ No newline at end of file From bb3d7e8046f0bf07dbcb17248cb11992224ff189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 20 Feb 2020 10:38:18 +0100 Subject: [PATCH 073/220] MOBILE-3352 behat: Behat basic test for assignment --- mod/assignment/tests/behat/app_basic_usage.feature | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index 8bc5c0a1d..eaf010553 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -134,7 +134,7 @@ Feature: Test basic usage of assignment activity in app And I should see "Submission test 2 attempt" @app @3.8.0 @OK - Scenario: Add submission offline (online text) + Scenario: Add submission offline (online text), submit for grading offline and sync submissions When I enter the app And I log in as "student1" Then the header should be "Acceptance test site" in the app @@ -156,6 +156,8 @@ Feature: Test basic usage of assignment activity in app And I switch offline mode to "false" And I press the back button in the app And I press "assignment1" in the app + And I press "Display options" in the app + And I press "Refresh" in the app Then I should not see "This Assignment has offline data to be synchronised." And I should see "Submitted for grading" From 1f04f85599f12fbf24793f6f2ba0a6e1dda88b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 22 Jan 2020 09:56:01 +0100 Subject: [PATCH 074/220] MDL-67728 behat: Improve behat app selectors --- app_behat_runtime.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/app_behat_runtime.js b/app_behat_runtime.js index 888a1571b..011215751 100644 --- a/app_behat_runtime.js +++ b/app_behat_runtime.js @@ -72,7 +72,7 @@ if (window.M.util.pending_js.length === 1) { runAfterEverything(function() { // Check there isn't a spinner... - updateSpinner(); + checkUIBlocked(); // Only remove it if the pending array is STILL empty after all that. if (window.M.util.pending_js.length === 1) { @@ -109,23 +109,23 @@ return realOpen.apply(this, arguments); }; - var waitingSpinner = false; + var waitingBlocked = false; /** * Checks if a loading spinner is present and visible; if so, adds it to the pending array * (and if not, removes it). */ - var updateSpinner = function() { - var spinner = document.querySelector('span.core-loading-spinner'); - if (spinner && spinner.offsetParent) { - if (!waitingSpinner) { - addPending('spinner'); - waitingSpinner = true; + var checkUIBlocked = function() { + var blocked = document.querySelector('span.core-loading-spinner, ion-loading, .click-block-active'); + if (blocked && blocked.offsetParent) { + if (!waitingBlocked) { + addPending('blocked'); + waitingBlocked = true; } } else { - if (waitingSpinner) { - removePending('spinner'); - waitingSpinner = false; + if (waitingBlocked) { + removePending('blocked'); + waitingBlocked = false; } } }; @@ -167,7 +167,7 @@ setTimeout(pollRecentMutation, 500); } // Also update the spinner presence if needed. - updateSpinner(); + checkUIBlocked(); }; // Set listener using the mutation callback. @@ -182,7 +182,9 @@ * @param {function} process Callback function that handles each matched node */ var findPossibleMatches = function(xpath, process) { - var matches = document.evaluate(xpath, document); + var select = 'ion-alert, ion-popover, ion-action-sheet, core-ion-tab.show-tab ion-page.show-page, ion-page.show-page, html'; + var parent = document.querySelector(select); + var matches = document.evaluate(xpath, parent || document); while (true) { var match = matches.iterateNext(); if (!match) { From 990472e02f80e3fe7b1878e29a296252f785e40f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 21 Jan 2020 12:43:51 +0100 Subject: [PATCH 075/220] MDL-67728 behat: Increase app start timeout --- behat_app.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/behat_app.php b/behat_app.php index 4996b2797..f82ce5d70 100644 --- a/behat_app.php +++ b/behat_app.php @@ -294,7 +294,7 @@ class behat_app extends behat_base { } } throw new DriverException('Moodle app not found in browser'); - }, false, 30); + }, false, 60); // Run the scripts to install Moodle 'pending' checks. $this->getSession()->executeScript( @@ -312,7 +312,7 @@ class behat_app extends behat_base { return 'mainpage'; } throw new DriverException('Moodle app login URL prompt not found'); - }, behat_base::get_extended_timeout(), 30); + }, behat_base::get_extended_timeout(), 60); // If it's the login page, we automatically fill in the URL and leave it on the user/pass // page. If it's the main page, we just leave it there. From bc261f9062cd56de3249066e8341ed89c1c85a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 24 Feb 2020 09:32:08 +0100 Subject: [PATCH 076/220] MOBILE-3353 behat: Behat basic test for quiz --- mod/quiz/tests/behat/app_basic_usage.feature | 135 +++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100755 mod/quiz/tests/behat/app_basic_usage.feature diff --git a/mod/quiz/tests/behat/app_basic_usage.feature b/mod/quiz/tests/behat/app_basic_usage.feature new file mode 100755 index 000000000..9e0a07911 --- /dev/null +++ b/mod/quiz/tests/behat/app_basic_usage.feature @@ -0,0 +1,135 @@ +@mod @mod_quiz @app @javascript +Feature: Attempt a quiz in app + As a student + In order to demonstrate what I know + I need to be able to attempt quizzes + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | + | student1 | + | teacher1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | teacher1 | C1 | editingteacher | + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | + And the following "question categories" exist: + | contextlevel | reference | name | + | Course | C1 | Test questions | + And the following "questions" exist: + | questioncategory | qtype | name | questiontext | + | Test questions | truefalse | TF1 | Text of the first question | + | Test questions | truefalse | TF2 | Text of the second question | + And quiz "Quiz 1" contains the following questions: + | question | page | + | TF1 | 1 | + | TF2 | 2 | + + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | quiz | Quiz 2 | Quiz 2 description | C1 | quiz2 | + And the following "question categories" exist: + | contextlevel | reference | name | + | Course | C1 | Test questions 2| + And the following "questions" exist: + | questioncategory | qtype | name | questiontext | + | Test questions | multichoice | TF3 | Text of the first question | + | Test questions | shortanswer | TF4 | Text of the second question | + | Test questions | numerical | TF5 | Text of the third question | + | Test questions | essay | TF6 | Text of the fourth question | + | Test questions | ddwtos | TF7 | Text of the fifth question | + | Test questions | truefalse | TF8 | Text of the sixth question | + | Test questions | match | TF9 | Text of the seventh question | + And quiz "Quiz 2" contains the following questions: + | question | page | + | TF3 | 1 | + | TF4 | 2 | + | TF5 | 3 | + | TF6 | 4 | + | TF7 | 5 | + | TF8 | 6 | + | TF9 | 7 | + + + @app @3.8.0 @OK + Scenario: View a quiz entry page (attempts, status, etc.) + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Quiz 1" in the app + And I press "Attempt quiz now" in the app + Then I should see "Text of the first question" + And I should not see "Text of the second question" + And I press "Next" near "Question 1" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Previous" near "Question 2" in the app + And I should not see "Text of the second question" + And I should see "Text of the first question" + And I press "Next" near "Quiz 1" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Previous" near "Quiz 1" in the app + And I should not see "Text of the second question" + And I should see "Text of the first question" + And I press "Next" near "Question 1" in the app + And I press "Next" near "Quiz 1" in the app + And I should see "Summary of attempt" + And I press "Return to attempt" in the app + And I should see "Text of the second question" + And I should not see "Text of the first question" + And I press "Next" in the app + And I press "Submit all and finish" in the app + Then I should see "Once you submit" + And I press "Cancel" near "Once you submit" in the app + And I should see "Summary of attempt" + And I press "Submit all and finish" in the app + And I press "OK" near "Once you submit" in the app + Then I should see "Review of attempt 1" + And I should see "Started on" + And I should see "State" + And I should see "Completed on" + And I should see "Time taken" + And I should see "Marks" + And I should see "Grade" + And I should see "Question 1" + And I should see "Question 2" + + @app @3.8.0 @OK + Scenario: Attempt a quiz (all question types) + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Quiz 2" in the app + And I press "Attempt quiz now" in the app + And I press "Four" in the app + And I press "Three" in the app + And I press "Next" near "Question 1" in the app + And I set the field "Answer" to "testing" in the app + And I press "Next" near "Question 2" in the app + And I set the field "Answer" to "5" in the app + And I press "Next" near "Question 3" in the app + And I set the field "Answer" to "Testing an essay" in the app + And I press "Next" near "Question 4" in the app + And I press "lazy" in the app + And I press "Next" near "Question 5" in the app + And I press "True" in the app + And I press "Next" near "Question 6" in the app + And I press "Choose..." near "frog" in the app + And I press "amphibian" in the app + And I press "Choose..." near "newt" in the app + And I press "insect" in the app + And I press "Choose..." near "cat" in the app + And I press "mammal" in the app + And I press "Next" near "Question 7" in the app + And I press "Submit all and finish" in the app + And I press "OK" in the app + Then I should see "Review of attempt 1" + And I should see "Finished" + And I should see "Not yet graded" \ No newline at end of file From 6442bb26c3bad89316ace3f58eb6c9058ef00a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 24 Feb 2020 10:13:51 +0100 Subject: [PATCH 077/220] MOBILE-3353 behat: Behat basic test for quiz --- mod/quiz/tests/behat/app_basic_usage.feature | 30 +++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/mod/quiz/tests/behat/app_basic_usage.feature b/mod/quiz/tests/behat/app_basic_usage.feature index 9e0a07911..6789cfdd9 100755 --- a/mod/quiz/tests/behat/app_basic_usage.feature +++ b/mod/quiz/tests/behat/app_basic_usage.feature @@ -132,4 +132,32 @@ Feature: Attempt a quiz in app And I press "OK" in the app Then I should see "Review of attempt 1" And I should see "Finished" - And I should see "Not yet graded" \ No newline at end of file + And I should see "Not yet graded" + + @app @3.8.0 @OK + Scenario: Submit a quiz and review a quiz attempt + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Quiz 1" in the app + And I press "Attempt quiz now" in the app + And I press "True" in the app + And I press "Next" near "Question 1" in the app + And I press "False" in the app + And I press "Next" near "Question 2" in the app + And I press "Submit all and finish" in the app + And I press "OK" in the app + Then I should see "Review of attempt 1" + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Course overview" in the app + And I press "Quiz 1" in the app + And I press "Display options" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I follow "Attempts: 1" + And I follow "Review attempt" + Then I should see "Finished" + And I should see "1.00/2.00" + And I close the browser tab opened by the app \ No newline at end of file From 0083a401cd858c2fada3e1715b8aa2fbf02c8029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Thu, 27 Feb 2020 11:41:03 +0100 Subject: [PATCH 078/220] MOBILE-3362 behat: Behat basic test for chat --- mod/chat/tests/behat/app_basic_usage.feature | 74 ++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100755 mod/chat/tests/behat/app_basic_usage.feature diff --git a/mod/chat/tests/behat/app_basic_usage.feature b/mod/chat/tests/behat/app_basic_usage.feature new file mode 100755 index 000000000..dc0c1184c --- /dev/null +++ b/mod/chat/tests/behat/app_basic_usage.feature @@ -0,0 +1,74 @@ +@mod @mod_chat @app @javascript +Feature: Test basic usage of chat in app + As a student + I need basic chat functionality to work + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | firstname | lastname | + | student1 | david | student | + | student2 | pau | student2 | + | teacher1 | juan | teacher | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | student2 | C1 | student | + | teacher1 | C1 | editingteacher | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | chat | Test chat name | Test chat | C1 | chat | 0 | + + @app @3.8.0 @OK + Scenario: Receive and send messages, see connected users, beep and talk to + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test chat name" in the app + Then I should see "Click here to enter the chat now" + And I should see "View past chat sessions" + And I press "Click here to enter the chat now" in the app + And I set the field "New message" to "Hi!" + And I press "Send" in the app + And I set the field "New message" to "I am David" + And I press "Send" in the app + When I enter the app + And I log in as "student2" + And I press "Course 1" near "Course overview" in the app + And I press "Test chat name" in the app + And I press "Click here to enter the chat now" in the app + Then I should see "Hi!" + And I should see "I am David" + And I press "people" in the app + Then I should see "david student" + And I press "Beep" in the app + Then I should see "You beeped david student" + And I set the field "New message" to "Hi David, I am Pau." + And I press "Send" in the app + + @app @3.8.0 @OK + Scenario: Past sessions shown for >=3.5 + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test chat name" in the app + Then I should see "Click here to enter the chat now" + And I should see "View past chat sessions" + And I press "Click here to enter the chat now" in the app + And I set the field "New message" to "Hi!" + And I press "Send" in the app + And I set the field "New message" to "I am David" + And I press "Send" in the app + When I enter the app + And I log in as "student2" + And I press "Course 1" near "Course overview" in the app + And I press "Test chat name" in the app + Then I should see "Click here to enter the chat now" + And I should see "View past chat sessions" + And I press "View past chat sessions" in the app + And I press "Show incomplete sessions" in the app + And I press "david student (2)" in the app + Then I should see "Hi!" + And I should see "I am David" \ No newline at end of file From 7325109de6f84302b9e6eaa75f09742498fa9a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 2 Mar 2020 10:46:24 +0100 Subject: [PATCH 079/220] MOBILE-3372 behat: Behat basic test for login --- mod/login/tests/behat/app_basic_usage.feature | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100755 mod/login/tests/behat/app_basic_usage.feature diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature new file mode 100755 index 000000000..445045ba7 --- /dev/null +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -0,0 +1,108 @@ +@mod @mod_login @app @javascript +Feature: Test basic usage of login in app + I need basic login functionality to work + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | firstname | lastname | + | student1 | david | student | + | student2 | pau | student2 | + | teacher1 | juan | teacher | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | student2 | C1 | student | + | teacher1 | C1 | editingteacher | + + @app @3.8.0 @OK + Scenario: Add a non existing site + When I enter the app + And I log in as "student1" + And I press "menu" in the app + And I press "Change site" in the app + And I press "add" in the app + And I set the field "Site address" to "Wrong Site Address" in the app + And I press "Connect!" in the app + Then I should see "Error" + And I should see "Double check you've entered the address correctly and try again." + + @app @3.8.0 @OK + Scenario: Delete a site + When I enter the app + And I log in as "student1" + And I press "menu" in the app + And I press "Change site" in the app + Then I should see "Acceptance test site" + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" in the app + Then I should not see "Acceptance test site" + And I should see "Connect to Moodle" + + @app @3.8.0 @mobile @OK + Scenario: Require minium version of the app for a site and site name in displayed when adding a new site (mobile) + When I enter the app + Then I should see "Acceptance test site" + And I log in as "teacher1" + And I press "menu" in the app + And I press "Website" in the app + And I switch to the browser tab opened by the app + And I follow "Log in" + And I log in as "admin" + And I press "Side panel" + And I follow "Site administration" + And I follow "Mobile authentication" + And I set the field "Minimum app version required" to "3.8.1" + And I press "Save changes" + And I close the browser tab opened by the app + When I enter the app + And I log in as "teacher1" + And I press "menu" in the app + And I press "Website" in the app + And I switch to the browser tab opened by the app + And I follow "Log in" + And I log in as "admin" + And I press "Side panel" + And I follow "Site administration" + And I follow "Mobile authentication" + And I set the field "Minimum app version required" to "3.8.2" + And I press "Save changes" + And I close the browser tab opened by the app + When I enter the app + Then I should see "App update required" + + @app @3.8.0 @tablet @OK + Scenario: Require minium version of the app for a site and site name in displayed when adding a new site (tablet) + When I enter the app + And I change viewport size to "1280x1080" + Then I should see "Acceptance test site" + And I log in as "teacher1" + And I press "menu" in the app + And I press "Website" in the app + And I switch to the browser tab opened by the app + And I follow "Log in" + And I log in as "admin" + And I follow "Site administration" + And I follow "Mobile authentication" + And I set the field "Minimum app version required" to "3.8.1" + And I press "Save changes" + And I close the browser tab opened by the app + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "teacher1" + And I press "menu" in the app + And I press "Website" in the app + And I switch to the browser tab opened by the app + And I follow "Log in" + And I log in as "admin" + And I follow "Site administration" + And I follow "Mobile authentication" + And I set the field "Minimum app version required" to "3.8.2" + And I press "Save changes" + And I close the browser tab opened by the app + When I enter the app + And I change viewport size to "1280x1080" + Then I should see "App update required" \ No newline at end of file From c0506d6ff0d99ba262efa623d5c218b44f182334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Wed, 4 Mar 2020 11:19:27 +0100 Subject: [PATCH 080/220] Fix on course and glossary behats --- mod/course/tests/behat/app_basic_usage.feature | 4 ++-- mod/glossary/tests/behat/app_basic_usage.feature | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index a42f3154b..c661d8822 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -495,7 +495,7 @@ Feature: Test basic usage of one course in app And I click on "Side panel" "button" And I follow "Add a block" And I follow "Activities" - And I click on "Actions menu" "icon" in the "#dropdown-0" "css_element" + And I click on "Actions menu" "icon" in the "#action-menu-toggle-0" "css_element" And I follow "Configure (new HTML block) block" And I set the field "HTML block title" to "HTML title test" And I set the field "Content" to "body test" @@ -544,7 +544,7 @@ Feature: Test basic usage of one course in app And I follow "HTML" And I follow "Add a block" And I follow "Activities" - And I click on "Actions menu" "icon" in the "#dropdown-0" "css_element" + And I click on "Actions menu" "icon" in the "#action-menu-toggle-0" "css_element" And I follow "Configure (new HTML block) block" And I set the field "HTML block title" to "HTML title test" And I set the field "Content" to "body test" diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index 285b878bb..3fedced35 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -83,15 +83,14 @@ Feature: Test basic usage of glossary in app And I should see "car" And I should see "mountain" And I should see "potato" - And I press "Browse entries" in the app And I press "Search" in the app And I set the field "Search query" to "something" in the app - And I press "search" in the app + And I press "search" near "No entries were found." in the app Then I should see "No entries were found." And I set the field "Search query" to "potato" in the app - And I press "search" in the app + And I press "search" near "No entries were found." in the app And I set the field "Search query" to " " in the app - And I press "potato" in the app + And I press "potato" near "glossary description" in the app Then I should see "potato" And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." From 154c0fbefd01de7b5132335d8c8ac077fff44f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 9 Mar 2020 09:35:47 +0100 Subject: [PATCH 081/220] Fixes on: MOBILE-3328, glossary --- .../tests/behat/app_basic_usage.feature | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index 3fedced35..f600e97fd 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -58,8 +58,8 @@ Feature: Test basic usage of glossary in app Then I should see "car" And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." - @app @3.8.0 @OK - Scenario: Change filters (include search) + @app @3.8.0 @mobile @OK + Scenario: Change filters (include search) (mobile) When I enter the app And I log in as "student1" Then the header should be "Acceptance test site" in the app @@ -90,7 +90,43 @@ Feature: Test basic usage of glossary in app And I set the field "Search query" to "potato" in the app And I press "search" near "No entries were found." in the app And I set the field "Search query" to " " in the app - And I press "potato" near "glossary description" in the app + And I press "potato" near "something" in the app + And I press "potato" in the app + Then I should see "potato" + And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." + + @app @3.8.0 @tablet @OK + Scenario: Change filters (include search) (tablet) + When I enter the app + And I change viewport size to "1280x1080" + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I press "Search" in the app + And I set the field "Search query" to "something" in the app + And I press "search" near "No entries were found." in the app + Then I should see "No entries were found." + And I set the field "Search query" to "potato" in the app + And I press "search" near "No entries were found." in the app Then I should see "potato" And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." From e507dd4131f3a2721be13ee4d95febb4be30a67f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Castell=C3=B3n?= Date: Mon, 9 Mar 2020 11:55:56 +0100 Subject: [PATCH 082/220] Fixes on: MOBILE-3328, glossary --- mod/glossary/tests/behat/app_basic_usage.feature | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index f600e97fd..67784dc39 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -90,7 +90,8 @@ Feature: Test basic usage of glossary in app And I set the field "Search query" to "potato" in the app And I press "search" near "No entries were found." in the app And I set the field "Search query" to " " in the app - And I press "potato" near "something" in the app + And I press "Display options" in the app + And I press "Refresh" in the app And I press "potato" in the app Then I should see "potato" And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." From 25bb9dd90664f8136b3478c2f6970aa04292badc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 20 May 2020 13:29:26 +0200 Subject: [PATCH 083/220] MDL-68789 behat: Adapt login step to new app version --- behat_app.php | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/behat_app.php b/behat_app.php index f82ce5d70..af82844ec 100644 --- a/behat_app.php +++ b/behat_app.php @@ -303,12 +303,22 @@ class behat_app extends behat_base { // Wait until the site login field appears OR the main page. $situation = $this->spin( function($context, $args) { - $input = $context->getSession()->getPage()->find('xpath', '//input[@name="url"]'); - if ($input) { + $page = $context->getSession()->getPage(); + + $element = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); + if ($element) { + // Wait for the onboarding modal to open, if any. + $this->wait_for_pending_js(); + $element = $page->find('xpath', '//page-core-login-site-onboarding'); + if ($element) { + $this->i_press_in_the_app('Skip'); + } + return 'login'; } - $mainmenu = $context->getSession()->getPage()->find('xpath', '//page-core-mainmenu'); - if ($mainmenu) { + + $element = $page->find('xpath', '//page-core-mainmenu'); + if ($element) { return 'mainpage'; } throw new DriverException('Moodle app login URL prompt not found'); @@ -317,7 +327,7 @@ class behat_app extends behat_base { // If it's the login page, we automatically fill in the URL and leave it on the user/pass // page. If it's the main page, we just leave it there. if ($situation === 'login') { - $this->i_set_the_field_in_the_app('Site address', $CFG->wwwroot); + $this->i_set_the_field_in_the_app('campus.example.edu', $CFG->wwwroot); $this->i_press_in_the_app('Connect!'); } From e0170317f3b4d1502ebd794ccdede10cf2c35d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 25 May 2020 11:37:31 +0200 Subject: [PATCH 084/220] MOBILE-3434 database: Update database behat --- mod/data/tests/behat/app_data_entries.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mod/data/tests/behat/app_data_entries.feature b/mod/data/tests/behat/app_data_entries.feature index 793f1fb38..b7765f2c6 100644 --- a/mod/data/tests/behat/app_data_entries.feature +++ b/mod/data/tests/behat/app_data_entries.feature @@ -118,7 +118,7 @@ Feature: Users can manage entries in database activities And I should see "Moodle Cloud" And I press "Delete" in the app And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app + And I press "Delete" in the app And I should not see "Moodle Cloud" And I press "Add entries" in the app And I set the field "URL" to "https://moodle.org/" in the app @@ -139,7 +139,7 @@ Feature: Users can manage entries in database activities And I should see "Moodle Cloud" And I press "Delete" in the app And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app + And I press "Delete" in the app And I should not see "Moodle Cloud" And I should see "No entries in database" @@ -176,7 +176,7 @@ Feature: Users can manage entries in database activities And I should see "Moodle Cloud" And I press "Delete" near "Moodle Cloud" in the app And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app + And I press "Delete" in the app And I should not see "Moodle Cloud" And I press "More" in the app And I should see "https://telegram.org/" @@ -195,5 +195,5 @@ Feature: Users can manage entries in database activities And I should see "Moodle Cloud" And I press "Delete" in the app And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app + And I press "Delete" in the app And I should not see "Moodle Cloud" From 15ad7c39f2bd0d321802ed543f5778805d8db39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 25 May 2020 12:12:19 +0200 Subject: [PATCH 085/220] MOBILE-3434 choice: Update choice behat --- mod/choice/tests/behat/app_basic_usage.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index d6054ad60..114370a4e 100644 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -58,6 +58,6 @@ Feature: Test basic usage in app And I should see "Option 3: 1" And I press "Remove my choice" in the app And I should see "Are you sure" - And I press "OK" in the app + And I press "Delete" in the app And I should not see "Remove my choice" And I should see "The results are not currently viewable" From 9ddcba012a7ada8e7cae19586491339057cc9b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 25 May 2020 12:37:10 +0200 Subject: [PATCH 086/220] MOBILE-3434 database: Update database sync behat feature --- mod/data/tests/behat/app_data_sync.feature | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mod/data/tests/behat/app_data_sync.feature b/mod/data/tests/behat/app_data_sync.feature index 025f1abcc..274132587 100644 --- a/mod/data/tests/behat/app_data_sync.feature +++ b/mod/data/tests/behat/app_data_sync.feature @@ -66,7 +66,7 @@ Feature: Users can store entries in database activities when offline and sync wh And I press "Save" near "Web links" in the app And I should see "https://moodle.org/" And I should see "Moodle community site" - And I press "Information" in the app + And I press "Display options" in the app And I press "Download" in the app And I wait until the page is ready And I switch offline mode to "true" @@ -87,13 +87,13 @@ Feature: Users can store entries in database activities when offline and sync wh And I should see "https://moodlecloud.com/" And I should see "Moodle Cloud" And I should not see "This Database has offline data to be synchronised" - And I press "Information" in the app + And I press "Display options" in the app And I press "Refresh" in the app And I wait until the page is ready And I switch offline mode to "true" And I press "Delete" in the app And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app + And I press "Delete" in the app And I should see "https://moodlecloud.com/" And I should see "Moodle Cloud" And I should see "This Database has offline data to be synchronised" @@ -117,13 +117,13 @@ Feature: Users can store entries in database activities when offline and sync wh And I press "Save" near "Web links" in the app And I should see "https://moodle.org/" And I should see "Moodle community site" - And I press "Information" in the app + And I press "Display options" in the app And I press "Download" in the app And I wait until the page is ready When I switch offline mode to "true" And I press "Delete" in the app And I should see "Are you sure you want to delete this entry?" - And I press "OK" in the app + And I press "Delete" in the app And I should see "https://moodle.org/" And I should see "Moodle community site" And I should see "This Database has offline data to be synchronised" From 27018ee73a1c69bde562dd78d5026d842d9b7075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 25 May 2020 14:00:55 +0200 Subject: [PATCH 087/220] MOBILE-3434 forum: Update forum behat --- mod/forum/tests/behat/app_basic_usage.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 099472334..0d0a83b7d 100644 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -28,7 +28,6 @@ Feature: Test basic usage in app And I set the field "Message" to "An awesome message" in the app And I press "Post to forum" in the app Then I should see "My happy subject" - And I should see "An awesome message" @app_upto3.6.1 Scenario: Student posts a reply From c73a00f6c9ee465d17099d3570aa1b51296d3c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 25 May 2020 14:53:18 +0200 Subject: [PATCH 088/220] MDL-68789 behat: Change app page menu text selector --- app_behat_runtime.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app_behat_runtime.js b/app_behat_runtime.js index 011215751..56fdbc3b3 100644 --- a/app_behat_runtime.js +++ b/app_behat_runtime.js @@ -410,7 +410,8 @@ case 'page menu' : // This lang string was changed in app version 3.6. selector = 'core-context-menu > button[aria-label=Info], ' + - 'core-context-menu > button[aria-label=Information]'; + 'core-context-menu > button[aria-label=Information], ' + + 'core-context-menu > button[aria-label="Display options"]'; break; default: return 'ERROR: Unsupported standard button type'; From 8a68b1c45b225099b10e24818e59ba6010ef027b Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 4 Jun 2020 13:19:15 +0200 Subject: [PATCH 089/220] MOBILE-3294: Fix and format behat tests --- .../tests/behat/app_basic_usage.feature | 323 +++-- mod/chat/tests/behat/app_basic_usage.feature | 45 +- .../tests/behat/app_basic_usage.feature | 114 +- .../tests/behat/app_basic_usage.feature | 795 ++++++------- .../tests/behat/app_basic_usage.feature | 944 +++++++-------- .../tests/behat/app_course_completion.feature | 36 + mod/course/tests/behat/app_courselist.feature | 120 ++ .../tests/behat/app_basic_usage.feature | 240 ++-- mod/forum/tests/behat/app_basic_usage.feature | 369 ++---- .../tests/behat/app_basic_usage.feature | 720 +++++------ mod/login/tests/behat/app_basic_usage.feature | 64 +- .../tests/behat/app_basic_usage.feature | 1052 ++++++----------- mod/quiz/tests/behat/app_basic_usage.feature | 71 +- .../tests/behat/app_basic_usage.feature | 927 ++++++--------- tests/behat/behat_local_moodlemobileapp.php | 100 ++ 15 files changed, 2589 insertions(+), 3331 deletions(-) create mode 100644 mod/course/tests/behat/app_course_completion.feature create mode 100644 mod/course/tests/behat/app_courselist.feature create mode 100644 tests/behat/behat_local_moodlemobileapp.php diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index eaf010553..775a0319c 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -16,182 +16,159 @@ Feature: Test basic usage of assignment activity in app | teacher1 | C1 | editingteacher | | student1 | C1 | student | And the following "activities" exist: - | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | duedate | attemptreopenmethod | - | assign | C1 | assign1 | assignment1 | Test assignment description1 | 1 | 1 | manual | + | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | duedate | attemptreopenmethod | + | assign | C1 | assign1 | assignment1 | Test assignment description1 | 1 | 1029844800 | manual | + @app @3.8.0 + Scenario: Create, edit and submit an assignment as a student, view it as a teacher + # Create, edit and submit as a student + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "assignment1" in the app + Then the header should be "assignment1" in the app + And I should see "Test assignment description1" + And I should see "Due date" + And I should see "Tuesday, 20 August 2002, 12:00 PM" - @app @3.8.0 @OK - Scenario: View assign and add a submission (online text), submit for grading, view own submission or student submission and view list of student submissions (as teacher) - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "assignment1" in the app - Then the header should be "assignment1" in the app - And I should see "Test assignment description1" - And I should see "Due date" - And I should see "Thursday, 1 January 1970, 1:00 AM" - And I press "Add submission" in the app - And I set the field "Online text submissions" to "Submission test" in the app - And I press "Save" in the app - Then I should see "Draft (not submitted)" - And I should see "Not graded" - And I press "Edit submission" in the app - And I set the field "Online text submissions" to "Submission test edited" in the app - And I press "Save" in the app - And I press "OK" in the app - And I press "Submit assignment" in the app - And I press "OK" in the app - Then I should see "Submitted for grading" - And I should see "Not graded" - And I should see "Submission test edited" - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "assignment1" in the app - Then the header should be "assignment1" in the app - And I press "Submitted" in the app - Then I should see "Student student" - And I should see "Not graded" - And I press "Student student" near "assignment1" in the app - Then I should see "Online text submission" - And I should see "Submission test edited" + When I press "Add submission" in the app + And I set the field "Online text submissions" to "Submission test" in the app + And I press "Save" in the app + Then I should see "Draft (not submitted)" + And I should see "Not graded" - @app @3.8.0 @OK + When I press "Edit submission" in the app + And I set the field "Online text submissions" to "Submission test edited" in the app + And I press "Save" in the app + And I press "OK" in the app + Then I should see "Submission test edited" + + When I press "Submit assignment" in the app + And I press "OK" in the app + Then I should see "Submitted for grading" + And I should see "Not graded" + And I should see "Submission test edited" + + # View as a teacher + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "assignment1" in the app + Then the header should be "assignment1" in the app + + When I press "Submitted" in the app + Then I should see "Student student" + And I should see "Not graded" + + When I press "Student student" near "assignment1" in the app + Then I should see "Online text submissions" + And I should see "Submission test edited" + + @app @3.8.0 Scenario: Add new attempt from previous submission - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "assignment1" in the app - Then the header should be "assignment1" in the app - And I should see "Test assignment description1" - And I should see "Due date" - And I should see "Thursday, 1 January 1970, 1:00 AM" - And I press "Add submission" in the app - And I set the field "Online text submissions" to "Submission test" in the app - And I press "Save" in the app - And I press "Submit assignment" in the app - And I press "OK" in the app - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "assignment1" in the app - Then the header should be "assignment1" in the app - And I press "Participants" in the app - Then I should see "Student student" - And I should see "Not graded" - And I press "Student student" near "assignment1" in the app - Then I should see "Online text submission" - And I should see "Submission test" - And I press "Grade" in the app - And I press "Allow another attempt" in the app - And I press "Done" - Then I should see "Reopened" - And I should see "Not graded" - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "assignment1" in the app - And I should see "Reopened" - And I should see "2 out of Unlimited" - And I should see "Add a new attempt based on previous submission" - And I should see "Add a new attempt" - And I press "Add a new attempt based on previous submission" in the app - And I press "OK" in the app - Then I should see "Submission test" - And I set the field "Online text submissions" to "Submission test 2 attempt" in the app - And I press "Save" in the app - And I press "OK" in the app - And I press "Submit assignment" in the app - And I press "OK" in the app - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "assignment1" in the app - Then the header should be "assignment1" in the app - And I press "Participants" in the app - Then I should see "Student student" - And I should see "Not graded" - And I press "Student student" near "assignment1" in the app - Then I should see "Online text submission" - And I should see "Submission test 2 attempt" + # Submit first attempt as a student + Given I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "assignment1" in the app + And I press "Add submission" in the app + And I set the field "Online text submissions" to "Submission test 1st attempt" in the app + And I press "Save" in the app + And I press "Submit assignment" in the app + And I press "OK" in the app - @app @3.8.0 @OK - Scenario: Add submission offline (online text), submit for grading offline and sync submissions - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "assignment1" in the app - Then the header should be "assignment1" in the app - And I should see "Test assignment description1" - And I should see "Due date" - And I should see "Thursday, 1 January 1970, 1:00 AM" - And I press "Add submission" in the app - And I switch offline mode to "true" - And I set the field "Online text submissions" to "Submission test" in the app - And I press "Save" in the app - And I press "Submit assignment" in the app - And I press "OK" in the app - Then I should see "This Assignment has offline data to be synchronised." - And I switch offline mode to "false" - And I press the back button in the app - And I press "assignment1" in the app - And I press "Display options" in the app - And I press "Refresh" in the app - Then I should not see "This Assignment has offline data to be synchronised." - And I should see "Submitted for grading" + # Allow more attempts as a teacher + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "assignment1" in the app + And I press "Participants" in the app + And I press "Student student" near "assignment1" in the app + And I press "Grade" in the app + And I press "Allow another attempt" in the app + And I press "Done" + Then I should see "Reopened" + And I should see "Not graded" - @app @3.8.0 @OK - Scenario: Edit an offline submission before synchronizing it - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "assignment1" in the app - Then the header should be "assignment1" in the app - And I should see "Test assignment description1" - And I should see "Due date" - And I should see "Thursday, 1 January 1970, 1:00 AM" - And I press "Add submission" in the app - And I switch offline mode to "true" - And I set the field "Online text submissions" to "Submission test1" in the app - And I press "Save" in the app - Then I should see "This Assignment has offline data to be synchronised." - And I should see "Submission test1" - And I press "Edit submission" in the app - And I set the field "Online text submissions" to "Submission test edited offline" in the app - And I press "Save" in the app - Then I should see "This Assignment has offline data to be synchronised." - And I should not see "Submission test1" - And I should see "Submission test edited offline" - And I press "Submit assignment" in the app - And I press "OK" in the app - Then I should see "This Assignment has offline data to be synchronised." - And I switch offline mode to "false" - And I press the back button in the app - And I press "assignment1" in the app - Then I should not see "This Assignment has offline data to be synchronised." - And I should see "Submitted for grading" - And I should see "Submission test edited offline" \ No newline at end of file + # Submit second attempt as a student + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "assignment1" in the app + Then I should see "Reopened" + And I should see "2 out of Unlimited" + And I should see "Add a new attempt based on previous submission" + And I should see "Add a new attempt" + + When I press "Add a new attempt based on previous submission" in the app + And I press "OK" in the app + Then I should see "Submission test 1st attempt" + + When I set the field "Online text submissions" to "Submission test 2nd attempt" in the app + And I press "Save" in the app + And I press "OK" in the app + And I press "Submit assignment" in the app + And I press "OK" in the app + + # View second attempt as a teacher + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "assignment1" in the app + And I press "Participants" in the app + And I press "Student student" near "assignment1" in the app + Then I should see "Online text submissions" + And I should see "Submission test 2nd attempt" + + @app @3.8.0 + Scenario: Add offline submission and synchronise it + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "assignment1" in the app + And I press "Add submission" in the app + And I switch offline mode to "true" + And I set the field "Online text submissions" to "Submission test" in the app + And I press "Save" in the app + And I press "Submit assignment" in the app + And I press "OK" in the app + Then I should see "This Assignment has offline data to be synchronised." + + When I switch offline mode to "false" + And I press the back button in the app + And I press "assignment1" in the app + And I press "Display options" in the app + And I press "Refresh" in the app + Then I should see "Submitted for grading" + But I should not see "This Assignment has offline data to be synchronised." + + @app @3.8.0 + Scenario: Edit an offline submission before synchronising it + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "assignment1" in the app + And I press "Add submission" in the app + And I switch offline mode to "true" + And I set the field "Online text submissions" to "Submission test original offline" in the app + And I press "Save" in the app + Then I should see "This Assignment has offline data to be synchronised." + And I should see "Submission test original offline" + + When I press "Edit submission" in the app + And I set the field "Online text submissions" to "Submission test edited offline" in the app + And I press "Save" in the app + Then I should see "This Assignment has offline data to be synchronised." + And I should see "Submission test edited offline" + But I should not see "Submission test original offline" + + When I press "Submit assignment" in the app + And I press "OK" in the app + Then I should see "This Assignment has offline data to be synchronised." + + When I switch offline mode to "false" + And I press the back button in the app + And I press "assignment1" in the app + Then I should see "Submitted for grading" + And I should see "Submission test edited offline" + But I should not see "This Assignment has offline data to be synchronised." diff --git a/mod/chat/tests/behat/app_basic_usage.feature b/mod/chat/tests/behat/app_basic_usage.feature index dc0c1184c..725287ea6 100755 --- a/mod/chat/tests/behat/app_basic_usage.feature +++ b/mod/chat/tests/behat/app_basic_usage.feature @@ -11,29 +11,33 @@ Feature: Test basic usage of chat in app | username | firstname | lastname | | student1 | david | student | | student2 | pau | student2 | - | teacher1 | juan | teacher | And the following "course enrolments" exist: | user | course | role | | student1 | C1 | student | | student2 | C1 | student | - | teacher1 | C1 | editingteacher | And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | | chat | Test chat name | Test chat | C1 | chat | 0 | - @app @3.8.0 @OK - Scenario: Receive and send messages, see connected users, beep and talk to + @app @3.8.0 + Scenario: Send and read messages, send beeps and view connected users + # Send messages as student1 When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test chat name" in the app Then I should see "Click here to enter the chat now" And I should see "View past chat sessions" - And I press "Click here to enter the chat now" in the app + + When I press "Click here to enter the chat now" in the app And I set the field "New message" to "Hi!" And I press "Send" in the app And I set the field "New message" to "I am David" And I press "Send" in the app + Then I should see "Hi!" + And I should see "I am David" + + # Read messages, view connected users, send beep and reply as student2 When I enter the app And I log in as "student2" And I press "Course 1" near "Course overview" in the app @@ -41,34 +45,37 @@ Feature: Test basic usage of chat in app And I press "Click here to enter the chat now" in the app Then I should see "Hi!" And I should see "I am David" - And I press "people" in the app - Then I should see "david student" - And I press "Beep" in the app - Then I should see "You beeped david student" - And I set the field "New message" to "Hi David, I am Pau." - And I press "Send" in the app - @app @3.8.0 @OK - Scenario: Past sessions shown for >=3.5 - When I enter the app + When I press "people" in the app + Then I should see "david student" + + When I press "Beep" in the app + Then I should see "You beeped david student" + + When I set the field "New message" to "Hi David, I am Pau." + And I press "Send" in the app + Then I should see "Hi David, I am Pau." + + @app @3.8.0 + Scenario: View past sessions shown for >=3.5 + # Send messages as student1 + Given I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test chat name" in the app - Then I should see "Click here to enter the chat now" - And I should see "View past chat sessions" And I press "Click here to enter the chat now" in the app And I set the field "New message" to "Hi!" And I press "Send" in the app And I set the field "New message" to "I am David" And I press "Send" in the app + + # Read messages from past sessions as student2 When I enter the app And I log in as "student2" And I press "Course 1" near "Course overview" in the app And I press "Test chat name" in the app - Then I should see "Click here to enter the chat now" - And I should see "View past chat sessions" And I press "View past chat sessions" in the app And I press "Show incomplete sessions" in the app And I press "david student (2)" in the app Then I should see "Hi!" - And I should see "I am David" \ No newline at end of file + And I should see "I am David" diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 22fd3ec66..30c30c48a 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -16,12 +16,9 @@ Feature: Test basic usage of choice activity in app | user | course | role | | teacher1 | C1 | editingteacher | | student1 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | option | - | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | - @app @3.8.0 @OK - Scenario: Student sends their single choice and views results. + @app @3.8.0 + Scenario: Student sends a single choice answer and views the results Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | @@ -32,20 +29,22 @@ Feature: Test basic usage of choice activity in app And I press "Option 1" in the app And I press "Option 2" in the app And I press "Save my choice" in the app - And I should see "Are you sure" - And I press "OK" in the app + Then I should see "Are you sure" + + When I press "OK" in the app Then I should see "Option 1: 0" And I should see "Option 2: 1" And I should see "Option 3: 0" - And I should not see "Remove my choice" - And I press the back button in the app + But I should not see "Remove my choice" + + When I press the back button in the app And I press "Test single choice name" in the app - And I should see "Option 1: 0" + Then I should see "Option 1: 0" And I should see "Option 2: 1" And I should see "Option 3: 0" - @app @3.8.0 @OK - Scenario: Student sends, changes and removes the multi choice + @app @3.8.0 + Scenario: Student sends, changes and removes a multi choice answer Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | @@ -60,20 +59,23 @@ Feature: Test basic usage of choice activity in app And I should see "Option 2: 1" And I should see "Option 3: 0" And I should see "Remove my choice" - And I press "Option 1" in the app + + When I press "Option 1" in the app And I press "Option 3" in the app And I press "Save my choice" in the app - And I should see "Option 1: 0" + Then I should see "Option 1: 0" And I should see "Option 2: 1" And I should see "Option 3: 1" - And I press "Remove my choice" in the app - And I should see "Are you sure" - And I press "Delete" in the app - And I should not see "Remove my choice" - And I should see "The results are not currently viewable" - @app @3.8.0 @OK - Scenario: Student answers, changes answer offline and sync + When I press "Remove my choice" in the app + Then I should see "Are you sure" + + When I press "Delete" in the app + Then I should see "The results are not currently viewable" + But I should not see "Remove my choice" + + @app @3.8.0 + Scenario: Student edits answer offline and synchronises Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | @@ -86,14 +88,16 @@ Feature: Test basic usage of choice activity in app And I press "Option 2" in the app And I press "Save my choice" in the app Then I should see "Are you sure" - And I press "OK" in the app + + When I press "OK" in the app And I press the back button in the app And I press "Test single choice name" in the app - Then I should not see "Option 1: 0" + Then I should see "This Choice has offline data to be synchronised." + But I should not see "Option 1: 0" And I should not see "Option 2: 1" And I should not see "Option 3: 0" - And I should see "This Choice has offline data to be synchronised." - And I switch offline mode to "false" + + When I switch offline mode to "false" And I press the back button in the app And I press "Test single choice name" in the app And I press "Display options" in the app @@ -101,10 +105,10 @@ Feature: Test basic usage of choice activity in app Then I should see "Option 1: 0" And I should see "Option 2: 1" And I should see "Option 3: 0" - And I should not see "This Choice has offline data to be synchronised." + But I should not see "This Choice has offline data to be synchronised." - @app @3.8.0 @OK - Scenario: Student answers, changes answer offline and auto-sync + @app @3.8.0 + Scenario: Student edits answer offline and the app synchronises automatically Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | @@ -116,23 +120,26 @@ Feature: Test basic usage of choice activity in app And I switch offline mode to "true" And I press "Option 2" in the app And I press "Save my choice" in the app - And I should see "Are you sure" - And I press "OK" in the app + Then I should see "Are you sure" + + When I press "OK" in the app And I switch offline mode to "false" - Then I should not see "Option 1: 0" + Then I should see "This Choice has offline data to be synchronised." + But I should not see "Option 1: 0" And I should not see "Option 2: 1" And I should not see "Option 3: 0" - And I should see "This Choice has offline data to be synchronised." - And I wait "600" seconds + + When I run cron tasks in the app Then I should see "Option 1: 0" And I should see "Option 2: 1" And I should see "Option 3: 0" - And I should not see "This Choice has offline data to be synchronised." + But I should not see "This Choice has offline data to be synchronised." - @app @3.8.0 @OK - Scenario: Prefetch + @app @3.8.0 + Scenario: Prefetch activity Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | + | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | When I enter the app And I log in as "student1" @@ -141,41 +148,47 @@ Feature: Test basic usage of choice activity in app And I press "Show download options" in the app And I press "cloud download" near "Test single choice name" in the app And I switch offline mode to "true" - And I press "Choice name" in the app - And I should see "There was a problem connecting to the site. Please check your connection and try again." - And I press "OK" in the app + And I press "Test multi choice name" in the app + Then I should see "There was a problem connecting to the site. Please check your connection and try again." + + When I press "OK" in the app And I press the back button in the app And I press "Test single choice name" in the app - And I press "Option 1" in the app And I press "Option 2" in the app And I press "Save my choice" in the app - And I should see "Are you sure" - And I press "OK" in the app + Then I should see "Are you sure" + + When I press "OK" in the app And I press the back button in the app And I press "Test single choice name" in the app - And I should not see "Option 1: 0" + Then I should see "This Choice has offline data to be synchronised." + But I should not see "Option 1: 0" And I should not see "Option 2: 1" And I should not see "Option 3: 0" - And I should see "This Choice has offline data to be synchronised." - And I switch offline mode to "false" + + When I switch offline mode to "false" And I press the back button in the app And I press "Test single choice name" in the app Then I should see "Option 1: 0" And I should see "Option 2: 1" And I should see "Option 3: 0" - And I should not see "This Choice has offline data to be synchronised." + But I should not see "This Choice has offline data to be synchronised." - @app @3.8.0 @OK + @app @3.8.0 Scenario: Download students choice in text format - When I enter the app + # Submit answer as student + Given the following "activities" exist: + | activity | name | intro | course | idnumber | option | + | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | + And I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Choice name" in the app - And I press "Option 1" in the app And I press "Option 2" in the app And I press "Save my choice" in the app - And I should see "Are you sure" And I press "OK" in the app + + # Download answers as teacher When I enter the app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app @@ -187,4 +200,3 @@ Feature: Test basic usage of choice activity in app And I press "Actions menu" And I follow "View 1 responses" And I press "Download in text format" - And I close the browser tab opened by the app \ No newline at end of file diff --git a/mod/comments/tests/behat/app_basic_usage.feature b/mod/comments/tests/behat/app_basic_usage.feature index 1971374f4..36ad7cd4a 100755 --- a/mod/comments/tests/behat/app_basic_usage.feature +++ b/mod/comments/tests/behat/app_basic_usage.feature @@ -9,489 +9,356 @@ Feature: Test basic usage of comments in app | username | firstname | lastname | email | | teacher1 | Teacher | teacher | teacher1@example.com | | student1 | Student | student | student1@example.com | - And the following "courses" exist: | fullname | shortname | category | | Course 1 | C1 | 0 | - And the following "course enrolments" exist: | user | course | role | | teacher1 | C1 | editingteacher | | student1 | C1 | student | - And the following "activities" exist: | activity | name | intro | course | idnumber | mainglossary | allowcomments | assessed | scale | | glossary | Test glossary | glossary description | C1 | gloss1 | 1 | 1 | 1 | 1 | - And the following "activities" exist: | activity | name | intro | course | idnumber | comments | | data | Data | Data info | C1 | data1 | 1 | + @app @3.8.0 + Scenario: Create and delete comments (database) + # Create database entry and comment as a teacher + Given I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Data" in the app + And I press "Display options" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I add a "Text input" field to "Data" database and I fill the form with: + | Field name | Test field name | + | Field description | Test field description | + And I press "Save" + And I close the browser tab opened by the app + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Data" in the app + And I press "add" in the app + And I set the field "Test field name" to "Test" in the app + And I press "Save" in the app + And I press "More" in the app + And I press "Comments (0)" in the app + And I press "close" in the app + And I set the field "Add a comment..." to "comment test teacher" in the app + And I press "Save comment" in the app + Then I should see "Comment created" + And I should see "comment test teacher" - @app @3.8.0 @OK - Scenario: Add comments and delete comments (database) - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Data" in the app - And I press "Display options" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "teacher1" - And I add a "Text input" field to "Data" database and I fill the form with: - | Field name | Test field name | - | Field description | Test field description | - And I press "Save" - And I close the browser tab opened by the app - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Data" in the app - And I press "add" in the app - And I set the field "Test field name" to "Test" in the app - And I press "Save" in the app - And I press "More" in the app - And I press "Comments (0)" in the app - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Comment created" - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Data" in the app - And I press "More" in the app - And I press "Comments (1)" in the app - And I press "close" in the app - And I set the field "Add a comment..." to "comment test student" in the app - And I press "Save comment" in the app - Then I should see "Comment created" - And I should see "comment test" - And I should see "comment test student" - And I press the back button in the app - And I should see "Comments (2)" - And I press "Comments (2)" in the app - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should see "comment test" - And I should not see "comment test student" - And I press the back button in the app - And I should see "Comments (1)" + When I press the back button in the app + And I should see "Comments (1)" - @app @3.8.0 @OK - Scenario: Add comments offline, delete comments offline and sync (database) - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Data" in the app - And I press "Display options" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "teacher1" - And I add a "Text input" field to "Data" database and I fill the form with: - | Field name | Test field name | - | Field description | Test field description | - And I press "Save" - And I close the browser tab opened by the app - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Data" in the app - And I press "add" in the app - And I set the field "Test field name" to "Test" in the app - And I press "Save" in the app - And I press "More" in the app - And I press "Comments (0)" in the app - And I switch offline mode to "true" - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "There are offline comments to be synchronised." - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (0)" - And I press "Comments (0)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should not see "There are offline comments to be synchronised." - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - And I press "Comments (1)" in the app - And I switch offline mode to "true" - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should see "There are offline comments to be synchronised." - And I should see "Deleted offline" - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - And I press "Comments (1)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should not see "There are offline comments to be synchronised." - And I should not see "comment test" - And I press the back button in the app - And I should see "Comments (0)" + # Create and delete comments as a student + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Data" in the app + And I press "More" in the app + And I press "Comments (1)" in the app + And I press "close" in the app + And I set the field "Add a comment..." to "comment test student" in the app + And I press "Save comment" in the app + Then I should see "Comment created" + And I should see "comment test teacher" + And I should see "comment test student" - @app @3.8.0 @OK - Scenario: Add comments and delete comments (glossary) - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "potato" in the app - And I press "Comments (0)" in the app - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Comment created" - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Test glossary" in the app - And I press "potato" in the app - And I press "Comments (1)" in the app - And I press "close" in the app - And I set the field "Add a comment..." to "comment test student" in the app - And I press "Save comment" in the app - Then I should see "Comment created" - And I should see "comment test" - And I should see "comment test student" - And I press the back button in the app - And I should see "Comments (2)" - And I press "Comments (2)" in the app - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should see "comment test" - And I should not see "comment test student" - And I press the back button in the app - And I should see "Comments (1)" + When I press the back button in the app + And I press "Comments (2)" in the app + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should see "comment test teacher" + But I should not see "comment test student" - @app @3.8.0 @OK - Scenario: Add comments offline, delete comments offline and sync (glossary) - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "potato" in the app - And I press "Comments (0)" in the app - And I switch offline mode to "true" - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "There are offline comments to be synchronised." - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (0)" - And I press "Comments (0)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should not see "There are offline comments to be synchronised." - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - And I press "Comments (1)" in the app - And I switch offline mode to "true" - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should see "There are offline comments to be synchronised." - And I should see "Deleted offline" - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - And I press "Comments (1)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should not see "There are offline comments to be synchronised." - And I should not see "comment test" - And I press the back button in the app - And I should see "Comments (0)" + When I press the back button in the app + Then I should see "Comments (1)" - @app @3.8.0 @mobile @OK - Scenario: Add comments and delete comments mobile (blogs) - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "menu" in the app - And I press "Website" in the app - And I switch to the browser tab opened by the app - And I follow "Log in" - And I log in as "teacher1" - And I click on "Side panel" "button" - And I follow "C1" - And I press "Actions menu" - And I follow "Turn editing on" - And I click on "Side panel" "button" - And I follow "Add a block" - And I follow "Blog menu" - And I follow "Add an entry about this course" - And I set the field "Entry title" to "Blog test" - And I set the field "Blog entry body" to "Blog body" - And I press "Save changes" - And I close the browser tab opened by the app - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "menu" in the app - And I press "Site blog" in the app - Then I should see "Blog test" - And I should see "Blog body" - And I should see "Comments (0)" - And I press "Comments (0)" in the app - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Comment created" - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - And I press "Comments (1)" in the app - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should not see "comment test" - And I press the back button in the app - And I should see "Comments (0)" + @app @3.8.0 + Scenario: Create and delete offline comments and synchronise (database) + Given I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Data" in the app + And I press "Display options" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I add a "Text input" field to "Data" database and I fill the form with: + | Field name | Test field name | + | Field description | Test field description | + And I press "Save" + And I close the browser tab opened by the app + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Data" in the app + And I press "add" in the app + And I set the field "Test field name" to "Test" in the app + And I press "Save" in the app + And I press "More" in the app + And I press "Comments (0)" in the app + And I switch offline mode to "true" + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "There are offline comments to be synchronised." + And I should see "comment test" - @app @3.8.0 @tablet @OK - Scenario: Add comments and delete comments tablet (blogs) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "menu" in the app - And I press "Website" in the app - And I switch to the browser tab opened by the app - And I follow "Log in" - And I log in as "teacher1" - And I follow "C1" - And I press "Actions menu" - And I follow "Turn editing on" - And I follow "Add a block" - And I follow "Blog menu" - And I follow "Add an entry about this course" - And I set the field "Entry title" to "Blog test" - And I set the field "Blog entry body" to "Blog body" - And I press "Save changes" - And I close the browser tab opened by the app - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Site blog" in the app - Then I should see "Blog test" - And I should see "Blog body" - And I should see "Comments (0)" - And I press "Comments (0)" in the app - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Comment created" - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - And I press "Comments (1)" in the app - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should not see "comment test" - And I press the back button in the app - And I should see "Comments (0)" + When I press the back button in the app + And I press "Comments (0)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should see "comment test" + But I should not see "There are offline comments to be synchronised." - @app @3.8.0 @mobile @OK - Scenario: Add comments offline, delete comments offline and sync mobile (blogs) - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "menu" in the app - And I press "Website" in the app - And I switch to the browser tab opened by the app - And I follow "Log in" - And I log in as "teacher1" - And I click on "Side panel" "button" - And I follow "C1" - And I press "Actions menu" - And I follow "Turn editing on" - And I click on "Side panel" "button" - And I follow "Add a block" - And I follow "Blog menu" - And I follow "Add an entry about this course" - And I set the field "Entry title" to "Blog test" - And I set the field "Blog entry body" to "Blog body" - And I press "Save changes" - And I close the browser tab opened by the app - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "menu" in the app - And I press "Site blog" in the app - Then I should see "Blog test" - And I should see "Blog body" - And I should see "Comments (0)" - And I press "Comments (0)" in the app - And I switch offline mode to "true" - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "There are offline comments to be synchronised." - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (0)" - And I press "Comments (0)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should not see "There are offline comments to be synchronised." - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - And I press "Comments (1)" in the app - And I switch offline mode to "true" - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should see "There are offline comments to be synchronised." - And I should see "Deleted offline" - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - And I press "Comments (1)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should not see "There are offline comments to be synchronised." - And I should not see "comment test" - And I press the back button in the app - And I should see "Comments (0)" + When I press the back button in the app + And I press "Comments (1)" in the app + And I switch offline mode to "true" + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should see "There are offline comments to be synchronised." + And I should see "Deleted offline" + And I should see "comment test" - @app @3.8.0 @tablet @OK - Scenario: Add comments offline, delete comments offline and sync tablet (blogs) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "menu" in the app - And I press "Website" in the app - And I switch to the browser tab opened by the app - And I follow "Log in" - And I log in as "teacher1" - And I follow "C1" - And I press "Actions menu" - And I follow "Turn editing on" - And I follow "Add a block" - And I follow "Blog menu" - And I follow "Add an entry about this course" - And I set the field "Entry title" to "Blog test" - And I set the field "Blog entry body" to "Blog body" - And I press "Save changes" - And I close the browser tab opened by the app - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Site blog" in the app - Then I should see "Blog test" - And I should see "Blog body" - And I should see "Comments (0)" - And I press "Comments (0)" in the app - And I switch offline mode to "true" - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "There are offline comments to be synchronised." - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (0)" - And I press "Comments (0)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should not see "There are offline comments to be synchronised." - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - And I press "Comments (1)" in the app - And I switch offline mode to "true" - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should see "There are offline comments to be synchronised." - And I should see "Deleted offline" - And I should see "comment test" - And I press the back button in the app - And I should see "Comments (1)" - And I press "Comments (1)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should not see "There are offline comments to be synchronised." - And I should not see "comment test" - And I press the back button in the app - And I should see "Comments (0)" \ No newline at end of file + When I press the back button in the app + And I press "Comments (1)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should not see "There are offline comments to be synchronised." + And I should not see "comment test" + + When I press the back button in the app + And I should see "Comments (0)" + + @app @3.8.0 + Scenario: Create and delete comments (glossary) + # Create glossary entry and comment as a teacher + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "potato" in the app + And I press "Comments (0)" in the app + And I press "close" in the app + And I set the field "Add a comment..." to "comment test teacher" in the app + And I press "Save comment" in the app + Then I should see "Comment created" + And I should see "comment test teacher" + And I press the back button in the app + And I should see "Comments (1)" + + # Create and delete comments as a student + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "potato" in the app + And I press "Comments (1)" in the app + And I press "close" in the app + And I set the field "Add a comment..." to "comment test student" in the app + And I press "Save comment" in the app + Then I should see "Comment created" + And I should see "comment test teacher" + And I should see "comment test student" + + When I press the back button in the app + And I press "Comments (2)" in the app + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should see "comment test teacher" + But I should not see "comment test student" + + When I press the back button in the app + And I should see "Comments (1)" + + @app @3.8.0 + Scenario: Create and delete offline comments and synchronise (glossary) + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "potato" in the app + And I press "Comments (0)" in the app + And I switch offline mode to "true" + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "There are offline comments to be synchronised." + And I should see "comment test" + + When I press the back button in the app + And I press "Comments (0)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should see "comment test" + But I should not see "There are offline comments to be synchronised." + + When I press the back button in the app + And I press "Comments (1)" in the app + And I switch offline mode to "true" + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should see "There are offline comments to be synchronised." + And I should see "Deleted offline" + And I should see "comment test" + + When I press the back button in the app + And I press "Comments (1)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should not see "There are offline comments to be synchronised." + And I should not see "comment test" + + When I press the back button in the app + And I should see "Comments (0)" + + @app @3.8.0 + Scenario: Create and delete comments (blogs) + # Create blog as a teacher + Given I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "menu" in the app + And I press "Website" in the app + And I switch to the browser tab opened by the app + And I follow "Log in" + And I log in as "teacher1" + And I click on "Side panel" "button" + And I follow "C1" + And I press "Turn editing on" + And I click on "Side panel" "button" + And I follow "Add a block" + And I follow "Blog menu" + And I follow "Add an entry about this course" + And I set the field "Entry title" to "Blog test" + And I set the field "Blog entry body" to "Blog body" + And I press "Save changes" + And I close the browser tab opened by the app + + # Create and delete comments as a student + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "menu" in the app + And I press "Site blog" in the app + Then I should see "Blog test" + And I should see "Blog body" + + When I press "Comments (0)" in the app + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Comment created" + And I should see "comment test" + + When I press the back button in the app + And I press "Comments (1)" in the app + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + But I should not see "comment test" + + When I press the back button in the app + Then I should see "Comments (0)" + + @app @3.8.0 + Scenario: Create and delete offline comments and synchronise (blogs) + # Create blog as a teacher + Given I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "menu" in the app + And I press "Website" in the app + And I switch to the browser tab opened by the app + And I follow "Log in" + And I log in as "teacher1" + And I click on "Side panel" "button" + And I follow "C1" + And I press "Turn editing on" + And I click on "Side panel" "button" + And I follow "Add a block" + And I follow "Blog menu" + And I follow "Add an entry about this course" + And I set the field "Entry title" to "Blog test" + And I set the field "Blog entry body" to "Blog body" + And I press "Save changes" + And I close the browser tab opened by the app + + # Create and delete comments as a student + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "menu" in the app + And I press "Site blog" in the app + Then I should see "Blog test" + And I should see "Blog body" + + When I press "Comments (0)" in the app + And I switch offline mode to "true" + And I press "close" in the app + And I set the field "Add a comment..." to "comment test" in the app + And I press "Save comment" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "There are offline comments to be synchronised." + And I should see "comment test" + + When I press the back button in the app + And I press "Comments (0)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should see "comment test" + But I should not see "There are offline comments to be synchronised." + + When I press the back button in the app + And I press "Comments (1)" in the app + And I switch offline mode to "true" + And I press "Delete" in the app + And I press "trash" in the app + And I press "Delete" near "Cancel" in the app + Then I should see "Comment deleted" + And I should see "There are offline comments to be synchronised." + And I should see "Deleted offline" + And I should see "comment test" + + When I press the back button in the app + And I press "Comments (1)" in the app + And I switch offline mode to "false" + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then I should not see "There are offline comments to be synchronised." + And I should not see "comment test" + + When I press the back button in the app + Then I should see "Comments (0)" diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index c661d8822..622ae2bfd 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -10,48 +10,37 @@ Feature: Test basic usage of one course in app | teacher1 | Teacher | teacher | teacher1@example.com | | student1 | Student | student | student1@example.com | | student2 | Student2 | student2 | student2@example.com | - And the following "courses" exist: | fullname | shortname | category | | Course 1 | C1 | 0 | - And the following "course enrolments" exist: | user | course | role | | teacher1 | C1 | editingteacher | | student1 | C1 | student | - And the following "activities" exist: | activity | name | intro | course | idnumber | option | section | | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 1 | - And the following "activities" exist: | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | section | | assign | C1 | assign1 | assignment | Test assignment description | 1 | 1 | - And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | assessed | scale[modgrade_type] | | forum | Test forum name | Test forum | C1 | forum | 0 | 5 | Point | - And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | section | | chat | Test chat name | Test chat | C1 | chat | 0 | 2 | - And the following "activities" exist: | activity | name | intro | course | idnumber | section | | data | Web links | Useful links | C1 | data1 | 4 | - And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | section | | lti | Test external name | Test external | C1 | external | 0 | 1 | - And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | section | | feedback | Test feedback name | Test feedback | C1 | feedback | 0 | 3 | - And the following "activities" exist: | activity | name | intro | course | idnumber | section | | glossary | Test glossary | glossary description | C1 | gloss1 | 5 | - And the following "activities" exist: | activity | name | intro | course | idnumber | section | | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 2 | @@ -59,518 +48,487 @@ Feature: Test basic usage of one course in app | contextlevel | reference | name | | Course | C1 | Test questions | And the following "questions" exist: - | questioncategory | qtype | name | questiontext | + | questioncategory | qtype | name | questiontext | | Test questions | truefalse | TF1 | Text of the first question | | Test questions | truefalse | TF2 | Text of the second question | And quiz "Quiz 1" contains the following questions: | question | page | | TF1 | 1 | | TF2 | 2 | - And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | section | | survey | Test survey name | Test survey | C1 | survey | 0 | 1 | - And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | | wiki | Test wiki name | Test wiki | C1 | wiki | 0 | - And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | section | | lesson | Test lesson name | Test lesson | C1 | lesson | 0 | 3 | - And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | section | | scorm | Test scorm name | Test scorm | C1 | scorm | 0 | 2 | - And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | section | | workshop | Test workshop name | Test workshop | C1 | workshop | 0 | 3 | - @app @3.8.0 @OK + @app @3.8.0 Scenario: Student views course contents - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test external name" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" - And I press "Choice course 1" in the app - Then the header should be "Choice course 1" in the app - And I press the back button in the app - And I press "assignment" in the app - Then the header should be "assignment" in the app - And I press the back button in the app - And I press "Test forum name" in the app - Then the header should be "Test forum name" in the app - And I press the back button in the app - And I press "Test chat name" in the app - Then the header should be "Test chat name" in the app - And I press the back button in the app - And I press "Web links" in the app - Then the header should be "Web links" in the app - And I press the back button in the app - And I press "Test external name" in the app - Then the header should be "Test external name" in the app - And I press the back button in the app - And I press "Test feedback name" in the app - And I press "OK" in the app - Then the header should be "Test feedback name" in the app - And I press the back button in the app - And I press "Test glossary" in the app - Then the header should be "Test glossary" in the app - And I press the back button in the app - And I press "Quiz 1" in the app - Then the header should be "Quiz 1" in the app - And I press the back button in the app - And I press "Test survey name" in the app - Then the header should be "Test survey name" in the app - And I press the back button in the app - And I press "Test wiki name" in the app - And I press "OK" in the app - Then the header should be "Test wiki name" in the app - And I press the back button in the app - And I press "Test lesson name" in the app - Then the header should be "Test lesson name" in the app - And I press the back button in the app - And I press "Test scorm name" in the app - Then the header should be "Test scorm name" in the app - And I press the back button in the app - And I press "Test workshop name" in the app - Then the header should be "Test workshop name" in the app - And I press the back button in the app + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test external name" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" - @app @3.8.0 @OK + When I press "Choice course 1" in the app + Then the header should be "Choice course 1" in the app + + When I press the back button in the app + And I press "assignment" in the app + Then the header should be "assignment" in the app + + When I press the back button in the app + And I press "Test forum name" in the app + Then the header should be "Test forum name" in the app + + When I press the back button in the app + And I press "Test chat name" in the app + Then the header should be "Test chat name" in the app + + When I press the back button in the app + And I press "Web links" in the app + Then the header should be "Web links" in the app + + When I press the back button in the app + And I press "Test external name" in the app + Then the header should be "Test external name" in the app + + When I press the back button in the app + And I press "Test feedback name" in the app + And I press "OK" in the app + Then the header should be "Test feedback name" in the app + + When I press the back button in the app + And I press "Test glossary" in the app + Then the header should be "Test glossary" in the app + + When I press the back button in the app + And I press "Quiz 1" in the app + Then the header should be "Quiz 1" in the app + + When I press the back button in the app + And I press "Test survey name" in the app + Then the header should be "Test survey name" in the app + + When I press the back button in the app + And I press "Test wiki name" in the app + And I press "OK" in the app + Then the header should be "Test wiki name" in the app + + When I press the back button in the app + And I press "Test lesson name" in the app + Then the header should be "Test lesson name" in the app + + When I press the back button in the app + And I press "Test scorm name" in the app + Then the header should be "Test scorm name" in the app + + When I press the back button in the app + And I press "Test workshop name" in the app + Then the header should be "Test workshop name" in the app + + @app @3.8.0 Scenario: Student views section contents - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test external name" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" - And I press "arrow dropdown" in the app - And I press "General" near "Sections" in the app - Then I should not see "Choice course 1" - And I should not see "assignment" - And I should see "Test forum name" - And I should not see "Test chat name" - And I should not see "Web links" - And I should not see "Test external name" - And I should not see "Test feedback name" - And I should not see "Test glossary" - And I should not see "Quiz 1" - And I should not see "Test survey name" - And I should see "Test wiki name" - And I should not see "Test lesson name" - And I should not see "Test scorm name" - And I should not see "Test workshop name" - And I press "Test forum name" in the app - Then the header should be "Test forum name" in the app - And I press the back button in the app - And I press "Test wiki name" in the app - And I press "OK" in the app - Then the header should be "Test wiki name" in the app - And I press the back button in the app - And I press "arrow dropdown" in the app - And I press "Topic 1" near "Sections" in the app - Then I should see "Choice course 1" - And I should see "assignment" - And I should not see "Test forum name" - And I should not see "Test chat name" - And I should not see "Web links" - And I should see "Test external name" - And I should not see "Test feedback name" - And I should not see "Test glossary" - And I should not see "Quiz 1" - And I should see "Test survey name" - And I should not see "Test wiki name" - And I should not see "Test lesson name" - And I should not see "Test scorm name" - And I should not see "Test workshop name" - And I press "Choice course 1" in the app - Then the header should be "Choice course 1" in the app - And I press the back button in the app - And I press "assignment" in the app - Then the header should be "assignment" in the app - And I press the back button in the app - And I press "Test external name" in the app - Then the header should be "Test external name" in the app - And I press the back button in the app - And I press "Test survey name" in the app - Then the header should be "Test survey name" in the app - And I press the back button in the app - And I press "arrow dropdown" in the app - And I press "Topic 2" near "Sections" in the app - Then I should not see "Choice course 1" - And I should not see "assignment" - And I should not see "Test forum name" - And I should see "Test chat name" - And I should not see "Web links" - And I should not see "Test external name" - And I should not see "Test feedback name" - And I should not see "Test glossary" - And I should see "Quiz 1" - And I should not see "Test survey name" - And I should not see "Test wiki name" - And I should not see "Test lesson name" - And I should see "Test scorm name" - And I should not see "Test workshop name" - And I press "Test chat name" in the app - Then the header should be "Test chat name" in the app - And I press the back button in the app - And I press "Quiz 1" in the app - Then the header should be "Quiz 1" in the app - And I press the back button in the app - And I press "Test scorm name" in the app - Then the header should be "Test scorm name" in the app - And I press the back button in the app - And I press "arrow dropdown" in the app - And I press "Topic 3" near "Sections" in the app - Then I should not see "Choice course 1" - And I should not see "assignment" - And I should not see "Test forum name" - And I should not see "Test chat name" - And I should not see "Web links" - And I should not see "Test external name" - And I should see "Test feedback name" - And I should not see "Test glossary" - And I should not see "Quiz 1" - And I should not see "Test survey name" - And I should not see "Test wiki name" - And I should see "Test lesson name" - And I should not see "Test scorm name" - And I should see "Test workshop name" - And I press "Test feedback name" in the app - And I press "OK" in the app - Then the header should be "Test feedback name" in the app - And I press the back button in the app - And I press "Test lesson name" in the app - Then the header should be "Test lesson name" in the app - And I press the back button in the app - And I press "Test workshop name" in the app - Then the header should be "Test workshop name" in the app - And I press the back button in the app - And I press "arrow dropdown" in the app - And I press "Topic 4" near "Sections" in the app - Then I should not see "Choice course 1" - And I should not see "assignment" - And I should not see "Test forum name" - And I should not see "Test chat name" - And I should see "Web links" - And I should not see "Test external name" - And I should not see "Test feedback name" - And I should not see "Test glossary" - And I should not see "Quiz 1" - And I should not see "Test survey name" - And I should not see "Test wiki name" - And I should not see "Test lesson name" - And I should not see "Test scorm name" - And I should not see "Test workshop name" - And I press "Web links" in the app - Then the header should be "Web links" in the app - And I press the back button in the app - And I press "arrow dropdown" in the app - And I press "Topic 5" near "Sections" in the app - Then I should not see "Choice course 1" - And I should not see "assignment" - And I should not see "Test forum name" - And I should not see "Test chat name" - And I should not see "Web links" - And I should not see "Test external name" - And I should not see "Test feedback name" - And I should see "Test glossary" - And I should not see "Quiz 1" - And I should not see "Test survey name" - And I should not see "Test wiki name" - And I should not see "Test lesson name" - And I should not see "Test scorm name" - And I should not see "Test workshop name" - And I press "Test glossary" in the app - Then the header should be "Test glossary" in the app - And I press the back button in the app + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test external name" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" - @app @3.8.0 @OK + When I press "arrow dropdown" in the app + And I press "General" near "Sections" in the app + Then I should see "Test forum name" + And I should see "Test wiki name" + But I should not see "Choice course 1" + And I should not see "assignment" + And I should not see "Test chat name" + And I should not see "Web links" + And I should not see "Test external name" + And I should not see "Test feedback name" + And I should not see "Test glossary" + And I should not see "Quiz 1" + And I should not see "Test survey name" + And I should not see "Test lesson name" + And I should not see "Test scorm name" + And I should not see "Test workshop name" + + When I press "Test forum name" in the app + Then the header should be "Test forum name" in the app + + When I press the back button in the app + And I press "Test wiki name" in the app + And I press "OK" in the app + Then the header should be "Test wiki name" in the app + + When I press the back button in the app + And I press "arrow dropdown" in the app + And I press "Topic 1" near "Sections" in the app + Then I should see "Choice course 1" + And I should see "assignment" + And I should see "Test external name" + And I should see "Test survey name" + But I should not see "Test forum name" + And I should not see "Test chat name" + And I should not see "Web links" + And I should not see "Test feedback name" + And I should not see "Test glossary" + And I should not see "Quiz 1" + And I should not see "Test wiki name" + And I should not see "Test lesson name" + And I should not see "Test scorm name" + And I should not see "Test workshop name" + + When I press "Choice course 1" in the app + Then the header should be "Choice course 1" in the app + + When I press the back button in the app + And I press "assignment" in the app + Then the header should be "assignment" in the app + + When I press the back button in the app + And I press "Test external name" in the app + Then the header should be "Test external name" in the app + + When I press the back button in the app + And I press "Test survey name" in the app + Then the header should be "Test survey name" in the app + + When I press the back button in the app + And I press "arrow dropdown" in the app + And I press "Topic 2" near "Sections" in the app + Then I should see "Quiz 1" + And I should see "Test chat name" + And I should see "Test scorm name" + But I should not see "Choice course 1" + And I should not see "assignment" + And I should not see "Test forum name" + And I should not see "Web links" + And I should not see "Test external name" + And I should not see "Test feedback name" + And I should not see "Test glossary" + And I should not see "Test survey name" + And I should not see "Test wiki name" + And I should not see "Test lesson name" + And I should not see "Test workshop name" + + When I press "Test chat name" in the app + Then the header should be "Test chat name" in the app + + When I press the back button in the app + And I press "Quiz 1" in the app + Then the header should be "Quiz 1" in the app + + When I press the back button in the app + And I press "Test scorm name" in the app + Then the header should be "Test scorm name" in the app + + When I press the back button in the app + And I press "arrow dropdown" in the app + And I press "Topic 3" near "Sections" in the app + Then I should see "Test feedback name" + And I should see "Test lesson name" + And I should see "Test workshop name" + But I should not see "Choice course 1" + And I should not see "assignment" + And I should not see "Test forum name" + And I should not see "Test chat name" + And I should not see "Web links" + And I should not see "Test external name" + And I should not see "Test glossary" + And I should not see "Quiz 1" + And I should not see "Test survey name" + And I should not see "Test wiki name" + And I should not see "Test scorm name" + + When I press "Test feedback name" in the app + And I press "OK" in the app + Then the header should be "Test feedback name" in the app + + When I press the back button in the app + And I press "Test lesson name" in the app + Then the header should be "Test lesson name" in the app + + When I press the back button in the app + And I press "Test workshop name" in the app + Then the header should be "Test workshop name" in the app + + When I press the back button in the app + And I press "arrow dropdown" in the app + And I press "Topic 4" near "Sections" in the app + Then I should see "Web links" + But I should not see "Choice course 1" + And I should not see "assignment" + And I should not see "Test forum name" + And I should not see "Test chat name" + And I should not see "Test external name" + And I should not see "Test feedback name" + And I should not see "Test glossary" + And I should not see "Quiz 1" + And I should not see "Test survey name" + And I should not see "Test wiki name" + And I should not see "Test lesson name" + And I should not see "Test scorm name" + And I should not see "Test workshop name" + + When I press "Web links" in the app + Then the header should be "Web links" in the app + + When I press the back button in the app + And I press "arrow dropdown" in the app + And I press "Topic 5" near "Sections" in the app + Then I should see "Test glossary" + But I should not see "Choice course 1" + And I should not see "assignment" + And I should not see "Test forum name" + And I should not see "Test chat name" + And I should not see "Web links" + And I should not see "Test external name" + And I should not see "Test feedback name" + And I should not see "Quiz 1" + And I should not see "Test survey name" + And I should not see "Test wiki name" + And I should not see "Test lesson name" + And I should not see "Test scorm name" + And I should not see "Test workshop name" + + When I press "Test glossary" in the app + Then the header should be "Test glossary" in the app + + @app @3.8.0 Scenario: Navigation between sections using the bottom arrows - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test external name" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" - And I press "arrow dropdown" in the app - And I press "General" near "Sections" in the app - Then I should see "General" - And I should not see "Topic 1" - And I should not see "Topic 2" - And I should not see "Topic 3" - And I should not see "Topic 4" - And I should not see "Topic 5" - And I press "arrow forward" near "Test wiki name" in the app - Then I should not see "General" - And I should see "Topic 1" - And I should not see "Topic 2" - And I should not see "Topic 3" - And I should not see "Topic 4" - And I should not see "Topic 5" - And I press "arrow forward" near "Test survey name" in the app - Then I should not see "General" - And I should not see "Topic 1" - And I should see "Topic 2" - And I should not see "Topic 3" - And I should not see "Topic 4" - And I should not see "Topic 5" - And I press "arrow forward" near "Test scorm name" in the app - Then I should not see "General" - And I should not see "Topic 1" - And I should not see "Topic 2" - And I should see "Topic 3" - And I should not see "Topic 4" - And I should not see "Topic 5" - And I press "arrow forward" near "Test workshop name" in the app - Then I should not see "General" - And I should not see "Topic 1" - And I should not see "Topic 2" - And I should not see "Topic 3" - And I should see "Topic 4" - And I should not see "Topic 5" - And I press "arrow forward" near "Web links" in the app - Then I should not see "General" - And I should not see "Topic 1" - And I should not see "Topic 2" - And I should not see "Topic 3" - And I should not see "Topic 4" - And I should see "Topic 5" - And I press "arrow back" near "Test glossary" in the app - Then I should not see "General" - And I should not see "Topic 1" - And I should not see "Topic 2" - And I should not see "Topic 3" - And I should see "Topic 4" - And I should not see "Topic 5" + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test external name" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" - @app @3.8.0 @OK + When I press "arrow dropdown" in the app + And I press "General" near "Sections" in the app + Then I should see "General" + But I should not see "Topic 1" + And I should not see "Topic 2" + And I should not see "Topic 3" + And I should not see "Topic 4" + And I should not see "Topic 5" + + When I press "arrow forward" near "Test wiki name" in the app + Then I should see "Topic 1" + But I should not see "General" + And I should not see "Topic 2" + And I should not see "Topic 3" + And I should not see "Topic 4" + And I should not see "Topic 5" + + When I press "arrow forward" near "Test survey name" in the app + Then I should see "Topic 2" + But I should not see "General" + And I should not see "Topic 1" + And I should not see "Topic 3" + And I should not see "Topic 4" + And I should not see "Topic 5" + + When I press "arrow forward" near "Test scorm name" in the app + Then I should see "Topic 3" + But I should not see "General" + And I should not see "Topic 1" + And I should not see "Topic 2" + And I should not see "Topic 4" + And I should not see "Topic 5" + + When I press "arrow forward" near "Test workshop name" in the app + Then I should see "Topic 4" + But I should not see "General" + And I should not see "Topic 1" + And I should not see "Topic 2" + And I should not see "Topic 3" + And I should not see "Topic 5" + + When I press "arrow forward" near "Web links" in the app + Then I should see "Topic 5" + But I should not see "General" + And I should not see "Topic 1" + And I should not see "Topic 2" + And I should not see "Topic 3" + And I should not see "Topic 4" + + When I press "arrow back" near "Test glossary" in the app + Then I should see "Topic 4" + But I should not see "General" + And I should not see "Topic 1" + And I should not see "Topic 2" + And I should not see "Topic 3" + And I should not see "Topic 5" + + @app @3.8.0 Scenario: Self enrol - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Display options" in the app - And I press "Course summary" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "teacher1" - And I press "Actions menu" - And I follow "More..." - And I follow "Users" - And I follow "Enrolment methods" - And I click on "Enable" "icon" in the "Self enrolment (Student)" "table_row" - And I close the browser tab opened by the app - When I enter the app - And I log in as "student2" - Then the header should be "Acceptance test site" in the app - And I press "Site home" in the app - And I press "Available courses" in the app - And I press "Course 1" in the app - And I press "Enrol me" in the app - And I press "OK" in the app - And I press "Contents" in the app - Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test external name" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" + Given I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Display options" in the app + And I press "Course summary" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "More..." + And I follow "Users" + And I follow "Enrolment methods" + And I click on "Enable" "icon" in the "Self enrolment (Student)" "table_row" + And I close the browser tab opened by the app + When I enter the app + And I log in as "student2" + And I press "Site home" in the app + And I press "Available courses" in the app + And I press "Course 1" in the app + And I press "Enrol me" in the app + And I press "OK" in the app + And I wait loading to finish in the app + And I press "Contents" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test external name" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" - @app @3.8.0 @OK + @app @3.8.0 Scenario: Guest access - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Display options" in the app - And I press "Course summary" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "teacher1" - And I press "Actions menu" - And I follow "More..." - And I follow "Users" - And I follow "Enrolment methods" - And I click on "Enable" "icon" in the "Guest access" "table_row" - And I close the browser tab opened by the app - When I enter the app - And I log in as "student2" - Then the header should be "Acceptance test site" in the app - And I press "Site home" in the app - And I press "Available courses" in the app - And I press "Course 1" in the app - Then I should see "Download course" - And I should see "Contents" - And I press "Contents" in the app - Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" + Given I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Display options" in the app + And I press "Course summary" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "More..." + And I follow "Users" + And I follow "Enrolment methods" + And I click on "Enable" "icon" in the "Guest access" "table_row" + And I close the browser tab opened by the app + When I enter the app + And I log in as "student2" + And I press "Site home" in the app + And I press "Available courses" in the app + And I press "Course 1" in the app + Then I should see "Download course" + And I should see "Contents" - @app @3.8.0 @mobile @OK - Scenario: View blocks bellow/beside contents also when All sections selected (mobile) - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Display options" in the app - And I press "Course summary" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "teacher1" - And I press "Actions menu" - And I follow "Turn editing on" - And I click on "Side panel" "button" - And I follow "Add a block" - And I follow "HTML" - And I click on "Side panel" "button" - And I follow "Add a block" - And I follow "Activities" - And I click on "Actions menu" "icon" in the "#action-menu-toggle-0" "css_element" - And I follow "Configure (new HTML block) block" - And I set the field "HTML block title" to "HTML title test" - And I set the field "Content" to "body test" - And I press "Save changes" - And I close the browser tab opened by the app - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test external name" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" - Then I should see "HTML title test" - And I should see "body test" - And I should see "Activities" + When I press "Contents" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" - @app @3.8.0 @tablet @OK - Scenario: View blocks bellow/beside contents also when All sections selected (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Display options" in the app - And I press "Course summary" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "teacher1" - And I press "Actions menu" - And I follow "Turn editing on" - And I follow "Add a block" - And I follow "HTML" - And I follow "Add a block" - And I follow "Activities" - And I click on "Actions menu" "icon" in the "#action-menu-toggle-0" "css_element" - And I follow "Configure (new HTML block) block" - And I set the field "HTML block title" to "HTML title test" - And I set the field "Content" to "body test" - And I press "Save changes" - And I close the browser tab opened by the app - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test external name" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" - Then I should see "HTML title test" - And I should see "body test" - And I should see "Activities" \ No newline at end of file + @app @3.8.0 + Scenario: View blocks bellow/beside contents also when All sections selected + Given I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Display options" in the app + And I press "Course summary" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Turn editing on" + And I click on "Side panel" "button" + And I follow "Add a block" + And I follow "HTML" + And I click on "Side panel" "button" + And I follow "Add a block" + And I follow "Activities" + And I click on "Actions menu" "icon" in the "#action-menu-toggle-0" "css_element" + And I follow "Configure (new HTML block) block" + And I set the field "HTML block title" to "HTML title test" + And I set the field "Content" to "body test" + And I press "Save changes" + And I close the browser tab opened by the app + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + Then the header should be "Course 1" in the app + And I should see "Choice course 1" + And I should see "assignment" + And I should see "Test forum name" + And I should see "Test chat name" + And I should see "Web links" + And I should see "Test external name" + And I should see "Test feedback name" + And I should see "Test glossary" + And I should see "Quiz 1" + And I should see "Test survey name" + And I should see "Test wiki name" + And I should see "Test lesson name" + And I should see "Test scorm name" + And I should see "Test workshop name" + And I should see "HTML title test" + And I should see "body test" + And I should see "Activities" diff --git a/mod/course/tests/behat/app_course_completion.feature b/mod/course/tests/behat/app_course_completion.feature new file mode 100644 index 000000000..f0c30baa9 --- /dev/null +++ b/mod/course/tests/behat/app_course_completion.feature @@ -0,0 +1,36 @@ +@core @core_course @app @javascript +Feature: Check course completion feature. + In order to track the progress of the course on mobile device + As a student + I need to be able to update the activity completion status. + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | student1 | Student | 1 | student1@example.com | + And the following "courses" exist: + | fullname | shortname | category | enablecompletion | + | Course 1 | C1 | 0 | 1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + + Scenario: Complete the activity manually by clicking at the completion checkbox. + Given the following "activities" exist: + | activity | name | course | idnumber | completion | completionview | + | forum | First forum | C1 | forum1 | 1 | 0 | + | forum | Second forum | C1 | forum2 | 1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + # Set activities as completed. + And I should see "0%" + And I press "Not completed: First forum. Select to mark as complete." in the app + And I should see "50%" + And I press "Not completed: Second forum. Select to mark as complete." in the app + And I should see "100%" + # Set activities as not completed. + And I press "Completed: First forum. Select to mark as not complete." in the app + And I should see "50%" + And I press "Completed: Second forum. Select to mark as not complete." in the app + And I should see "0%" diff --git a/mod/course/tests/behat/app_courselist.feature b/mod/course/tests/behat/app_courselist.feature new file mode 100644 index 000000000..70d8b6606 --- /dev/null +++ b/mod/course/tests/behat/app_courselist.feature @@ -0,0 +1,120 @@ +@core @core_course @app @javascript +Feature: Test course list shown on app start tab + In order to select a course + As a student + I need to see the correct list of courses + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + | Course 2 | C2 | + And the following "users" exist: + | username | + | student1 | + | student2 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | student2 | C1 | student | + | student2 | C2 | student | + + Scenario: Student is registered on one course + When I enter the app + And I log in as "student1" + Then I should see "Course 1" + And I should not see "Course 2" + + Scenario: Student is registered on two courses (shortnames not displayed) + When I enter the app + And I log in as "student2" + Then I should see "Course 1" + And I should see "Course 2" + And I should not see "C1" + And I should not see "C2" + + Scenario: Student is registered on two courses (shortnames displayed) + Given the following config values are set as admin: + | courselistshortnames | 1 | + When I enter the app + And I log in as "student2" + Then I should see "Course 1" + And I should see "Course 2" + And I should see "C1" + And I should see "C2" + + Scenario: Student uses course list to enter course, then leaves it again + When I enter the app + And I log in as "student2" + And I press "Course 2" near "Course overview" in the app + Then the header should be "Course 2" in the app + And I press the back button in the app + Then the header should be "Acceptance test site" in the app + + Scenario: Student uses filter feature to reduce course list + Given the following config values are set as admin: + | courselistshortnames | 1 | + And the following "courses" exist: + | fullname | shortname | + | Frog 3 | C3 | + | Frog 4 | C4 | + | Course 5 | C5 | + | Toad 6 | C6 | + And the following "course enrolments" exist: + | user | course | role | + | student2 | C3 | student | + | student2 | C4 | student | + | student2 | C5 | student | + | student2 | C6 | student | + # Create bogus courses so that the main ones aren't shown in the 'recently accessed' part. + # Because these come later in alphabetical order, they may not be displayed in the lower part + # which is OK. + And the following "courses" exist: + | fullname | shortname | + | Zogus 1 | Z1 | + | Zogus 2 | Z2 | + | Zogus 3 | Z3 | + | Zogus 4 | Z4 | + | Zogus 5 | Z5 | + | Zogus 6 | Z6 | + | Zogus 7 | Z7 | + | Zogus 8 | Z8 | + | Zogus 9 | Z9 | + | Zogus 10 | Z10 | + And the following "course enrolments" exist: + | user | course | role | + | student2 | Z1 | student | + | student2 | Z2 | student | + | student2 | Z3 | student | + | student2 | Z4 | student | + | student2 | Z5 | student | + | student2 | Z6 | student | + | student2 | Z7 | student | + | student2 | Z8 | student | + | student2 | Z9 | student | + | student2 | Z10 | student | + When I enter the app + And I log in as "student2" + Then I press "Display options" near "Course overview" in the app + Then I should see "C1" + And I should see "C2" + And I should see "C3" + And I should see "C4" + And I should see "C5" + And I should see "C6" + Then I press "Filter my courses" in the app + And I set the field "Filter my courses" to "fr" in the app + Then I should not see "C1" + And I should not see "C2" + And I should see "C3" + And I should see "C4" + And I should not see "C5" + And I should not see "C6" + And I press "Display options" near "Course overview" in the app + And I press "Filter my courses" in the app + Then I should see "C1" + And I should see "C2" + And I should see "C3" + And I should see "C4" + And I should see "C5" + And I should see "C6" diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index cf3244604..fc5c12cd9 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -9,14 +9,12 @@ Feature: Test basic usage of courses in app | username | firstname | lastname | email | | teacher1 | Teacher | teacher | teacher1@example.com | | student1 | Student | student | student1@example.com | - And the following "courses" exist: | fullname | shortname | category | | Course 1 | C1 | 0 | | Course 2 | C2 | 0 | | Course 3 | C3 | 0 | | Course 4 | C4 | 0 | - And the following "course enrolments" exist: | user | course | role | | teacher1 | C1 | editingteacher | @@ -26,137 +24,133 @@ Feature: Test basic usage of courses in app | student1 | C1 | student | | student1 | C2 | student | | student1 | C3 | student | - And the following "activities" exist: | activity | name | intro | course | idnumber | option | - | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | - | choice | Choice course 2 | Test choice description | C2 | choice1 | Option 1, Option 2, Option 3 | - | choice | Choice course 3 | Test choice description | C3 | choice1 | Option 1, Option 2, Option 3 | - | choice | Choice course 4 | Test choice description | C4 | choice1 | Option 1, Option 2, Option 3 | - + | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 2 | Test choice description | C2 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 3 | Test choice description | C3 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 4 | Test choice description | C4 | choice1 | Option 1, Option 2, Option 3 | And the following "activities" exist: | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | | assign | C1 | assign1 | assignment | Test assignment description | 1 | - @app @3.8.0 @OK + @app @3.8.0 Scenario: Dashboard tab displayed in >= 3.3 sites - When I enter the app - And I log in as "student1" - Then I should see "Dashboard" - And the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" - And I press "Site home" in the app - Then I should see "Dashboard" - And the header should be "Acceptance test site" in the app - And I press "Dashboard" in the app - Then I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" + When I enter the app + And I log in as "student1" + Then I should see "Dashboard" + And the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" - @app @3.8.0 @OK + When I press "Site home" in the app + Then I should see "Dashboard" + And the header should be "Acceptance test site" in the app + + When I press "Dashboard" in the app + Then I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" + + @app @3.8.0 Scenario: See my courses - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" - And I press "Course 1" near "Recently accessed courses" in the app - Then I should see "Choice course 1" - And the header should be "Course 1" in the app - And I press "Choice course 1" in the app - Then I should see "Test choice description" - And the header should be "Choice course 1" in the app - And I press the back button in the app - And I press the back button in the app - And I press "Course 2" near "Recently accessed courses" in the app - Then I should see "Choice course 2" - And the header should be "Course 2" in the app - And I press the back button in the app - And I press "Course 3" near "Recently accessed courses" in the app - Then I should see "Choice course 3" - And the header should be "Course 3" in the app + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" - @app @3.8.0 @OK + When I press "Course 1" near "Recently accessed courses" in the app + Then I should see "Choice course 1" + And the header should be "Course 1" in the app + + When I press "Choice course 1" in the app + Then I should see "Test choice description" + And the header should be "Choice course 1" in the app + + When I press the back button in the app + And I press the back button in the app + And I press "Course 2" near "Recently accessed courses" in the app + Then I should see "Choice course 2" + And the header should be "Course 2" in the app + + When I press the back button in the app + And I press "Course 3" near "Recently accessed courses" in the app + Then I should see "Choice course 3" + And the header should be "Course 3" in the app + + @app @3.8.0 Scenario: Search for a course - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" - And I press "Search courses" in the app - And I set the field "Search" to "Course 4" in the app - And I press "Search" in the app - Then I should see "Course 4" - And the header should be "Search courses" in the app - And I press "Course 4" in the app - Then I should see "Course 4" - And the header should be "Course 4" in the app - And I press the back button in the app - And I set the field "Search" to "Course" in the app - And I press "Search" in the app - Then I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" - And I should see "Course 4" + When I enter the app + And I log in as "student1" + And I press "Search courses" in the app + And I set the field "Search" to "Course 4" in the app + And I press "Search" in the app + Then I should see "Course 4" + And the header should be "Search courses" in the app - @app @3.8.0 @OK + When I press "Course 4" in the app + Then I should see "Course 4" + And the header should be "Course 4" in the app + + When I press the back button in the app + And I set the field "Search" to "Course" in the app + And I press "Search" in the app + Then I should see "Course 1" + And I should see "Course 2" + And I should see "Course 3" + And I should see "Course 4" + + @app @3.8.0 Scenario: Links to actions in Timeline work for teachers/students - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" - And I should see "Timeline" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "assignment" in the app - And I press "Display options" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "teacher1" - And I press "Actions menu" - And I follow "Edit settings" - And I press "Expand all" - And I click on "duedate[enabled]" "checkbox" - And I click on "gradingduedate[enabled]" "checkbox" - And I press "Save and return to course" - And I close the browser tab opened by the app - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" - And I should see "Timeline" - And I press "Add submission" in the app - Then the header should be "assignment" in the app - And I should see "Test assignment description" - And I should see "No attempt" - And I should see "Due date" - And I press "Add submission" in the app - And I set the field "Online text submissions" to "test" in the app - And I press "Save" in the app - And I press "Submit assignment" in the app - And I press "OK" in the app - Then the header should be "assignment" in the app - And I should see "Test assignment description" - And I should see "Submitted for grading" - And I should see "Due date" - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" - And I should see "Timeline" - And I press "Grade" in the app - Then the header should be "assignment" in the app - And I should see "Test assignment description" - And I should see "Time remaining" - And I press "Needs grading" in the app - Then I should see "Student student" - And I should see "Not graded" \ No newline at end of file + # Configure assignment as teacher + When I enter the app + And I log in as "teacher1" + Then I should see "Timeline" + + Given I press "Course 1" near "Recently accessed courses" in the app + And I press "assignment" in the app + And I press "Display options" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "Edit settings" + And I press "Expand all" + And I click on "duedate[enabled]" "checkbox" + And I click on "gradingduedate[enabled]" "checkbox" + And I press "Save and return to course" + And I close the browser tab opened by the app + + # Submit assignment as student + When I enter the app + And I log in as "student1" + And I press "Add submission" in the app + Then the header should be "assignment" in the app + And I should see "Test assignment description" + And I should see "No attempt" + And I should see "Due date" + + When I press "Add submission" in the app + And I set the field "Online text submissions" to "test" in the app + And I press "Save" in the app + And I press "Submit assignment" in the app + And I press "OK" in the app + Then the header should be "assignment" in the app + And I should see "Test assignment description" + And I should see "Submitted for grading" + And I should see "Due date" + + # Grade assignment as teacher + When I enter the app + And I log in as "teacher1" + And I press "Grade" in the app + Then the header should be "assignment" in the app + And I should see "Test assignment description" + And I should see "Time remaining" + + When I press "Needs grading" in the app + Then I should see "Student student" + And I should see "Not graded" diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index d913a45a0..6484fa0dc 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -24,8 +24,8 @@ Feature: Test basic usage of forum activity in app | activity | name | intro | course | idnumber | groupmode | assessed | scale | | forum | Test forum name | Test forum | C1 | forum | 0 | 1 | 1 | - @app @3.8.0 @OK - Scenario: Student starts a discussion + @app @3.8.0 + Scenario: Student starts a discussion When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -35,11 +35,12 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "An awesome message" in the app And I press "Post to forum" in the app Then I should see "My happy subject" - And I press "My happy subject" in the app - And I should see "An awesome message" - @app_from3.7 - Scenario: Student posts a reply + When I press "My happy subject" in the app + Then I should see "An awesome message" + + @app_from3.7 + Scenario: Student posts a reply When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -55,73 +56,45 @@ Feature: Test basic usage of forum activity in app Then I should see "DiscussionMessage" And I should see "ReplyMessage" - @app @3.8.0 @mobile @OK - Scenario: Student stars a discussion (mobile) + @app @3.8.0 + Scenario: Student stars a discussion When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app And I press "close" in the app - And I set the field "Subject" to "Auto-test star" in the app - And I set the field "Message" to "Auto-test star message" in the app + And I set the field "Subject" to "starred subject" in the app + And I set the field "Message" to "starred message" in the app And I press "Post to forum" in the app - And I wait "60" seconds And I press "close" in the app - And I set the field "Subject" to "Auto-test star" in the app - And I set the field "Message" to "Auto-test no star message" in the app + And I set the field "Subject" to "normal subject" in the app + And I set the field "Message" to "normal message" in the app And I press "Post to forum" in the app - And I press "Auto-test star" near "Last post a minute ago" in the app - Then I should see "Auto-test star message" - And I press the back button in the app - And I press "Display options" near "Last post a minute ago" in the app - And I press "Star this discussion" in the app - And I press "Auto-test star" near "Last post a minute ago" in the app - Then I should see "Auto-test star message" - And I press the back button in the app - And I press "Auto-test star" near "Last post a few seconds ago" in the app - Then I should see "Auto-test no star message" - And I press the back button in the app - And I press "Display options" near "Last post a minute ago" in the app - And I press "Unstar this discussion" in the app - And I press "Auto-test star" near "Last post a few seconds ago" in the app - Then I should see "Auto-test no star message" - And I press the back button in the app - And I press "Auto-test star" near "Last post a minute ago" in the app - Then I should see "Auto-test star message" + And I press "starred subject" in the app + Then I should see "starred message" - @app @3.8.0 @tablet @OK - Scenario: Student stars a discussion (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - And I press "close" in the app - And I set the field "Subject" to "Auto-test star" in the app - And I set the field "Message" to "Auto-test star message" in the app - And I press "Post to forum" in the app - And I wait "60" seconds - And I press "close" in the app - And I set the field "Subject" to "Auto-test star" in the app - And I set the field "Message" to "Auto-test no star message" in the app - And I press "Post to forum" in the app - And I press "Auto-test star" near "Last post a minute ago" in the app - Then I should see "Auto-test star message" - And I press "Display options" near "Last post a minute ago" in the app + When I press the back button in the app + And I press "Display options" near "starred subject" in the app And I press "Star this discussion" in the app - And I press "Auto-test star" near "Last post a minute ago" in the app - Then I should see "Auto-test star message" - And I press "Auto-test star" near "Last post a few seconds ago" in the app - Then I should see "Auto-test no star message" - And I press "Display options" near "Last post a minute ago" in the app - And I press "Unstar this discussion" in the app - And I press "Auto-test star" near "Last post a few seconds ago" in the app - Then I should see "Auto-test no star message" - And I press "Auto-test star" near "Last post a minute ago" in the app - Then I should see "Auto-test star message" + And I press "starred subject" in the app + Then I should see "starred message" - @app @3.8.0 @OK - Scenario: Teacher star and pin a discussion + When I press the back button in the app + And I press "normal subject" in the app + Then I should see "normal message" + + When I press the back button in the app + And I press "Display options" near "starred subject" in the app + And I press "Unstar this discussion" in the app + And I press "starred subject" in the app + Then I should see "starred message" + + When I press the back button in the app + And I press "normal subject" in the app + Then I should see "normal message" + + @app @3.8.0 + Scenario: Teacher star and pin a discussion When I enter the app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app @@ -142,18 +115,19 @@ Feature: Test basic usage of forum activity in app And I press "Star this discussion" in the app And I press "Display options" near "Auto-test pin" in the app And I press "Pin this discussion" in the app - And I should see "Auto-test pin" + Then I should see "Auto-test pin" And I should see "Auto-test star" And I should see "Auto-test" - And I press "Display options" near "Auto-test pin" in the app + + When I press "Display options" near "Auto-test pin" in the app And I press "Unpin this discussion" in the app And I press "Display options" near "Auto-test star" in the app And I press "Unstar this discussion" in the app Then I should see "Auto-test star" And I should see "Auto-test pin" - @app_upto3.6.0 @OK - Scenario: Teacher checks pin and star in 3.6 + @app_upto3.6.0 + Scenario: Teacher checks pin and star in 3.6 When I enter the app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app @@ -167,8 +141,8 @@ Feature: Test basic usage of forum activity in app Then I should not see "Star this discussion" And I should not see "Pin this discussion" - @app @3.8.0 @mobile @OK - Scenario: Edit a not sent reply offline (mobile) + @app @3.8.0 + Scenario: Edit a not sent reply offline When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -184,48 +158,21 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app And I press "Display options" near "not sent reply" in the app Then I should see "Edit" - And I press "Edit" in the app + + When I press "Edit" in the app And I set the field "Write your reply..." to "not sent reply edited" in the app And I press "Post to forum" in the app Then I should see "Not sent" And I should see "This Discussion has offline data to be synchronised" - And I switch offline mode to "false" + + When I switch offline mode to "false" And I press the back button in the app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app Then I should not see "Not sent" And I should not see "This Discussion has offline data to be synchronised" - @app @3.8.0 @tablet @OK - Scenario: Edit a not sent reply offline (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - And I press "close" in the app - And I set the field "Subject" to "Auto-test" in the app - And I set the field "Message" to "Auto-test message" in the app - And I press "Post to forum" in the app - And I press "Auto-test" near "Sort by last post creation date in descending order" in the app - And I switch offline mode to "true" - And I press "Reply" in the app - And I set the field "Write your reply..." to "not sent reply" in the app - And I press "Post to forum" in the app - And I press "Display options" near "not sent reply" in the app - Then I should see "Edit" - And I press "Edit" in the app - And I set the field "Write your reply..." to "not sent reply edited" in the app - And I press "Post to forum" in the app - Then I should see "Not sent" - And I should see "This Discussion has offline data to be synchronised" - And I switch offline mode to "false" - And I press the back button in the app - And I press "Test forum name" in the app - Then I should not see "Not sent" - And I should not see "This Discussion has offline data to be synchronised" - - @app @3.8.0 @OK - Scenario: Edit a not sent new discussion offline + @app @3.8.0 + Scenario: Edit a not sent new discussion offline When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -239,15 +186,17 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "Auto-test message edited" in the app And I press "Post to forum" in the app Then I should see "This Forum has offline data to be synchronised." - And I switch offline mode to "false" + + When I switch offline mode to "false" And I press "Auto-test" in the app And I press "Post to forum" in the app Then I should not see "This Forum has offline data to be synchronised." - And I press "Auto-test" near "Sort by last post creation date in descending order" in the app + + When I press "Auto-test" near "Sort by last post creation date in descending order" in the app And I should see "Auto-test message edited" - @app @3.8.0 @OK - Scenario: Edit a forum post (only online) + @app @3.8.0 + Scenario: Edit a forum post (only online) When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -257,7 +206,8 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app Then I should see "Auto-test" - And I press the back button in the app + + When I press the back button in the app And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app @@ -265,17 +215,19 @@ Feature: Test basic usage of forum activity in app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app And I press "Display options" near "Reply" in the app Then I should see "Edit" - And I press "Edit" in the app + + When I press "Edit" in the app And I set the field "Write your reply..." to "Auto-test message edited" in the app And I press "Save changes" in the app And I switch offline mode to "true" And I press "Display options" near "Reply" in the app Then I should see "There was a problem connecting to the site. Please check your connection and try again." - And I press "OK" in the app + + When I press "OK" in the app And I should not see "Edit" - @app @3.8.0 @OK - Scenario: Delete a forum post (only online) + @app @3.8.0 + Scenario: Delete a forum post (only online) When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -285,7 +237,8 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app Then I should see "Auto-test" - And I press the back button in the app + + When I press the back button in the app And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app @@ -293,22 +246,25 @@ Feature: Test basic usage of forum activity in app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app And I press "Display options" near "Reply" in the app Then I should see "Delete" - And I press "Delete" in the app + + When I press "Delete" in the app And I press "Cancel" in the app And I switch offline mode to "true" And I press "Display options" near "Reply" in the app Then I should see "There was a problem connecting to the site. Please check your connection and try again." - And I press "OK" in the app - And I should not see "Delete" - And I switch offline mode to "false" + + When I press "OK" in the app + Then I should not see "Delete" + + When I switch offline mode to "false" And I press "Display options" near "Reply" in the app And I press "Delete" in the app And I press "Delete" in the app Then I should not see "Auto-test" - @app @3.8.0 @mobile @OK - Scenario: Add/view ratings (mobile) - When I enter the app + @app @3.8.0 + Scenario: Add/view ratings + Given I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app @@ -333,16 +289,20 @@ Feature: Test basic usage of forum activity in app Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." And I should see "Average of ratings: -" And I should see "Average of ratings: 1" - And I switch offline mode to "false" + + When I switch offline mode to "false" And I press the back button in the app Then I should see "This Forum has offline data to be synchronised." - And I press "Display options" near "Test forum name" in the app + + When I press "Display options" near "Test forum name" in the app And I press "Synchronise now" in the app - And I should not see "This Forum has offline data to be synchronised." - And I press "Auto-test" in the app + Then I should not see "This Forum has offline data to be synchronised." + + When I press "Auto-test" in the app Then I should see "Average of ratings: 1" And I should see "Average of ratings: 0" - And I should not see "Average of ratings: -" + But I should not see "Average of ratings: -" + When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -350,54 +310,10 @@ Feature: Test basic usage of forum activity in app And I press "Auto-test" in the app Then I should see "Average of ratings: 1" And I should see "Average of ratings: 0" - And I should not see "Average of ratings: -" + But I should not see "Average of ratings: -" - @app @3.8.0 @tablet @OK - Scenario: Add/view ratings (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - And I press "close" in the app - And I set the field "Subject" to "Auto-test" in the app - And I set the field "Message" to "Auto-test message" in the app - And I press "Post to forum" in the app - And I press "Reply" in the app - And I set the field "Write your reply..." to "test2" in the app - And I press "Post to forum" in the app - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - And I press "None" near "Auto-test message" in the app - And I press "1" near "Cancel" in the app - And I switch offline mode to "true" - And I press "None" near "test2" in the app - And I press "0" near "Cancel" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "Average of ratings: -" - And I should see "Average of ratings: 1" - And I switch offline mode to "false" - Then I should see "This Forum has offline data to be synchronised." - And I press "Display options" near "Test forum name" in the app - And I press "Synchronise now" in the app - And I should not see "This Forum has offline data to be synchronised." - Then I should see "Average of ratings: 1" - And I should see "Average of ratings: 0" - And I should not see "Average of ratings: -" - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - Then I should see "Average of ratings: 1" - And I should see "Average of ratings: 0" - And I should not see "Average of ratings: -" - - @app @3.8.0 @mobile @OK - Scenario: Student replies a post offline mobile + @app @3.8.0 + Scenario: Student replies a post offline When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -419,47 +335,16 @@ Feature: Test basic usage of forum activity in app Then I should see "DiscussionMessage" And I should see "ReplyMessage" And I should see "Not sent" - And I press the back button in the app + + When I press the back button in the app And I switch offline mode to "false" And I press "DiscussionSubject" in the app Then I should see "DiscussionMessage" And I should see "ReplyMessage" - And I should not see "Not sent" + But I should not see "Not sent" - @app @3.8.0 @tablet @OK - Scenario: Student replies a post offline tablet - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app - And I set the field "Subject" to "DiscussionSubject" in the app - And I set the field "Message" to "DiscussionMessage" in the app - And I press "Post to forum" in the app - And I press the back button in the app - And I press "Display options" in the app - And I press "Show download options" in the app - And I press "cloud download" near "Test forum name" in the app - And I press "Test forum name" in the app - And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app - And I switch offline mode to "true" - And I press "Reply" in the app - And I set the field "Write your reply" to "ReplyMessage" in the app - And I press "Post to forum" in the app - Then I should see "DiscussionMessage" - And I should see "ReplyMessage" - And I should see "Not sent" - And I press the back button in the app - And I switch offline mode to "false" - And I press "Test forum name" in the app - And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app - Then I should see "DiscussionMessage" - And I should see "ReplyMessage" - And I should not see "Not sent" - - @app @3.8.0 @OK - Scenario: Student creates a new discussion offline and sync forum + @app @3.8.0 + Scenario: Student creates a new discussion offline and sync forum When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -472,7 +357,8 @@ Feature: Test basic usage of forum activity in app Then I should see "DiscussionSubject" And I should see "Not sent" And I should see "This Forum has offline data to be synchronised." - And I switch offline mode to "false" + + When I switch offline mode to "false" And I press the back button in the app And I press "Test forum name" in the app And I press "Display options" near "Test forum name" in the app @@ -480,11 +366,11 @@ Feature: Test basic usage of forum activity in app And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app Then I should see "DiscussionSubject" And I should see "DiscussionMessage" - And I should not see "Not sent" + But I should not see "Not sent" And I should not see "This Forum has offline data to be synchronised." - @app @3.8.0 @OK - Scenario: Student creates a new discussion offline and auto-sync forum + @app @3.8.0 + Scenario: Student creates a new discussion offline and auto-sync forum When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -497,17 +383,20 @@ Feature: Test basic usage of forum activity in app Then I should see "DiscussionSubject" And I should see "Not sent" And I should see "This Forum has offline data to be synchronised." - And I switch offline mode to "false" - And I wait "600" seconds - And I should not see "Not sent" - And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app + + When I switch offline mode to "false" + And I run cron tasks in the app + And I wait loading to finish in the app + Then I should not see "Not sent" + + When I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app Then I should see "DiscussionSubject" And I should see "DiscussionMessage" - And I should not see "Not sent" + But I should not see "Not sent" And I should not see "This Forum has offline data to be synchronised." - @app @3.8.0 @mobile @OK - Scenario: Prefetch mobile + @app @3.8.0 + Scenario: Prefetch When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -517,7 +406,8 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app Then I should see "DiscussionSubject" - And I press the back button in the app + + When I press the back button in the app And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test forum name" in the app @@ -528,51 +418,16 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app Then I should see "DiscussionSubject" And I should see "DiscussionSubject 2" - And I press the back button in the app + + When I press the back button in the app And I switch offline mode to "true" And I press "Test forum name" in the app And I press "DiscussionSubject 2" in the app Then I should see "There was a problem connecting to the site. Please check your connection and try again." - And I press "OK" in the app - And I press the back button in the app - And I press "DiscussionSubject" in the app - Then I should see "DiscussionSubject" - And I should see "DiscussionMessage" - And I should not see "There was a problem connecting to the site. Please check your connection and try again." - @app @3.8.0 @tablet @OK - Scenario: Prefetch tablet - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app - And I set the field "Subject" to "DiscussionSubject" in the app - And I set the field "Message" to "DiscussionMessage" in the app - And I press "Post to forum" in the app - Then I should see "DiscussionSubject" + When I press "OK" in the app And I press the back button in the app - And I press "Display options" in the app - And I press "Show download options" in the app - And I press "cloud download" near "Test forum name" in the app - And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app - And I set the field "Subject" to "DiscussionSubject 2" in the app - And I set the field "Message" to "DiscussionMessage 2" in the app - And I press "Post to forum" in the app - Then I should see "DiscussionSubject" - And I should see "DiscussionSubject 2" - And I press the back button in the app - And I switch offline mode to "true" - And I press "refresh" near "Test forum name" in the app - Then I should see "There was a problem connecting to the site. Please check your connection and try again." - And I press "OK" in the app - And I press "Test forum name" in the app And I press "DiscussionSubject" in the app Then I should see "DiscussionSubject" And I should see "DiscussionMessage" - And I press the back button in the app - And I switch offline mode to "false" - And I press "refresh" near "Test forum name" in the app - Then I should not see "There was a problem connecting to the site. Please check your connection and try again." \ No newline at end of file + But I should not see "There was a problem connecting to the site. Please check your connection and try again." diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index 67784dc39..b4b0e81ae 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -10,449 +10,333 @@ Feature: Test basic usage of glossary in app | teacher1 | Teacher | teacher | teacher1@example.com | | teacher2 | Teacher2 | teacher2 | teacher2@example.com | | student1 | Student | student | student1@example.com | - And the following "courses" exist: | fullname | shortname | category | | Course 1 | C1 | 0 | - And the following "course enrolments" exist: | user | course | role | | teacher1 | C1 | editingteacher | | teacher2 | C1 | editingteacher | | student1 | C1 | student | - And the following "activities" exist: | activity | name | intro | course | idnumber | mainglossary | allowcomments | assessed | scale | | glossary | Test glossary | glossary description | C1 | gloss1 | 1 | 1 | 1 | 1 | - And the following "activities" exist: | activity | name | intro | course | idnumber | groupmode | | forum | Test forum name | Test forum | C1 | forum | 0 | - @app @3.8.0 @OK + @app @3.8.0 Scenario: View a glossary and its terms - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I press "car" in the app - Then I should see "car" - And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" - @app @3.8.0 @mobile @OK - Scenario: Change filters (include search) (mobile) - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I press "Search" in the app - And I set the field "Search query" to "something" in the app - And I press "search" near "No entries were found." in the app - Then I should see "No entries were found." - And I set the field "Search query" to "potato" in the app - And I press "search" near "No entries were found." in the app - And I set the field "Search query" to " " in the app - And I press "Display options" in the app - And I press "Refresh" in the app - And I press "potato" in the app - Then I should see "potato" - And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." + When I press "car" in the app + Then I should see "car" + And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." - @app @3.8.0 @tablet @OK - Scenario: Change filters (include search) (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I press "Search" in the app - And I set the field "Search query" to "something" in the app - And I press "search" near "No entries were found." in the app - Then I should see "No entries were found." - And I set the field "Search query" to "potato" in the app - And I press "search" near "No entries were found." in the app - Then I should see "potato" - And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." + @app @3.8.0 + Scenario: Change filters (include search) + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" - @app @3.8.0 @OK + When I press "Search" in the app + And I set the field "Search query" to "something" in the app + And I press "search" near "No entries were found." in the app + Then I should see "No entries were found." + + When I set the field "Search query" to "potato" in the app + And I press "search" near "No entries were found." in the app + And I set the field "Search query" to " " in the app + And I press "Display options" in the app + And I press "Refresh" in the app + And I press "potato" in the app + Then I should see "potato" + And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." + + @app @3.8.0 Scenario: Navigate to glossary terms by link (auto-linking) - And the "glossary" filter is "on" - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "This entry should be automatically linked" in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "This entry should be automatically linked" in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "This entry should be automatically linked" in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I press the back button in the app - And I press "Test forum name" in the app - And I press "add" in the app - And I set the field "Subject" to "Testing auto-link glossary" - And I set the field "Message" to "Glossary terms auto-linked: potato car mountain" in the app - And I press "Post to forum" in the app - And I press "Testing auto-link glossary" near "Last post a few seconds ago" in the app - And I press "car" in the app - Then the header should be "car" in the app - And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." - And I press the back button in the app - And I press "mountain" in the app - Then the header should be "mountain" in the app - And I should see "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." + When the "glossary" filter is "on" + And I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "This entry should be automatically linked" in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "This entry should be automatically linked" in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "This entry should be automatically linked" in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" - @app @3.8.0 @OK + When I press the back button in the app + And I press "Test forum name" in the app + And I press "add" in the app + And I set the field "Subject" to "Testing auto-link glossary" + And I set the field "Message" to "Glossary terms auto-linked: potato car mountain" in the app + And I press "Post to forum" in the app + And I press "Testing auto-link glossary" near "Last post a few seconds ago" in the app + And I press "car" in the app + Then the header should be "car" in the app + And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." + + When I press the back button in the app + And I press "mountain" in the app + Then the header should be "mountain" in the app + And I should see "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." + + @app @3.8.0 Scenario: See comments - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I press "mountain" in the app - Then I should see "Comments (0)" - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - Then I should see "Comments (0)" - And I press "Comments" in the app - And I should see "No comments" - And I press "close" in the app - And I set the field "Add a comment..." to "teacherComment" in the app - And I press "Save comment" in the app - Then I should see "teacherComment" - And I press "close" in the app - And I set the field "Add a comment..." to "teacherComment2" in the app - And I press "Save comment" in the app - Then I should see "teacherComment" - And I should see "teacherComment2" - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - Then I should see "Comments (2)" - And I press "Comments" in the app - And I should see "teacherComment" - And I should see "teacherComment2" + # Create entries as a student + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" - @app @3.8.0 @OK + When I press "mountain" in the app + Then I should see "Comments (0)" + + # Write comments as a teacher + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + Then I should see "Comments (0)" + + When I press "Comments" in the app + And I should see "No comments" + + When I press "close" in the app + And I set the field "Add a comment..." to "teacher first comment" in the app + And I press "Save comment" in the app + Then I should see "teacher first comment" + + When I press "close" in the app + And I set the field "Add a comment..." to "teacher second comment" in the app + And I press "Save comment" in the app + Then I should see "teacher first comment" + And I should see "teacher second comment" + + # View comments as a student + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + Then I should see "Comments (2)" + + When I press "Comments" in the app + And I should see "teacher first comment" + And I should see "teacher second comment" + + @app @3.8.0 Scenario: Prefetch - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I press "Display options" in the app - And I press "Download" in the app - And I press the back button in the app - And I press the back button in the app - And I press "Course 1" near "Recently accessed courses" in the app - And I switch offline mode to "true" - And I press "Test glossary" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I press "mountain" in the app - Then I should see "mountain" - And I should see "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." - And I should not see "Comments cannot be retrieved" - And I should see "Comments (0)" + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" - @app @3.8.0 @OK + When I press "Display options" in the app + And I press "Download" in the app + And I press the back button in the app + And I press the back button in the app + And I press "Course 1" near "Recently accessed courses" in the app + And I switch offline mode to "true" + And I press "Test glossary" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + + When I press "mountain" in the app + Then I should see "mountain" + And I should see "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." + And I should not see "Comments cannot be retrieved" + And I should see "Comments (0)" + + @app @3.8.0 Scenario: Sync - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I switch offline mode to "true" - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I should see "Entries to be synced" - And I should see "This Glossary has offline data to be synchronised." - And I switch offline mode to "false" - And I press "close" in the app - And I set the field "Concept" to "testSync" in the app - And I set the field "Definition" to "testSync" in the app - And I press "Save" in the app - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I should see "testSync" - And I should not see "Entries to be synced" - And I should not see "This Glossary has offline data to be synchronised." + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I switch offline mode to "true" + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I should see "Entries to be synced" + And I should see "This Glossary has offline data to be synchronised." - @app @3.8.0 @mobile @OK - Scenario: Add/view ratings (mobile) - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - Then I should see "Average of ratings: -" - And I press "None" in the app - And I press "1" in the app - Then I should see "Average of ratings: 1" - When I enter the app - And I log in as "teacher2" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - And I switch offline mode to "true" - And I press "None" in the app - And I press "0" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "Average of ratings: 1" - And I switch offline mode to "false" - And I press the back button in the app - Then I should see "This Glossary has offline data to be synchronised." - And I press "Display options" in the app - And I press "Synchronise now" in the app - And I press "mountain" in the app - Then I should see "Average of ratings: 0.5" - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - Then the header should be "mountain" in the app - And I should not see "Average of ratings: 0.5" + When I switch offline mode to "false" + And I press "close" in the app + And I set the field "Concept" to "testSync" in the app + And I set the field "Definition" to "testSync" in the app + And I press "Save" in the app + And I press "Display options" in the app + And I press "Synchronise now" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + And I should see "testSync" + But I should not see "Entries to be synced" + And I should not see "This Glossary has offline data to be synchronised." - @app @3.8.0 @tablet @OK - Scenario: Add/view ratings (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - Then I should see "Average of ratings: -" - And I press "None" in the app - And I press "1" in the app - Then I should see "Average of ratings: 1" - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "teacher2" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - And I switch offline mode to "true" - And I press "None" in the app - And I press "0" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "Average of ratings: 1" - And I switch offline mode to "false" - Then I should see "This Glossary has offline data to be synchronised." - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should see "Average of ratings: 0.5" - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - Then the header should be "Course 1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - Then I should not see "Average of ratings: 0.5" \ No newline at end of file + @app @3.8.0 + Scenario: Add/view ratings + # Create entries as a student + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "close" in the app + And I set the field "Concept" to "potato" in the app + And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "car" in the app + And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app + And I press "Save" in the app + And I press "close" in the app + And I set the field "Concept" to "mountain" in the app + And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app + And I press "Save" in the app + Then the header should be "Test glossary" in the app + And I should see "car" + And I should see "mountain" + And I should see "potato" + + # Rate entries as teacher1 + When I enter the app + And I log in as "teacher1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + Then I should see "Average of ratings: -" + + When I press "None" in the app + And I press "1" in the app + Then I should see "Average of ratings: 1" + + # Rate entries as teacher2 + When I enter the app + And I log in as "teacher2" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + And I switch offline mode to "true" + And I press "None" in the app + And I press "0" in the app + Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." + And I should see "Average of ratings: 1" + + When I switch offline mode to "false" + And I press the back button in the app + Then I should see "This Glossary has offline data to be synchronised." + + When I press "Display options" in the app + And I press "Synchronise now" in the app + And I press "mountain" in the app + Then I should see "Average of ratings: 0.5" + + # View ratings as a student + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Test glossary" in the app + And I press "mountain" in the app + Then the header should be "mountain" in the app + But I should not see "Average of ratings: 0.5" diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index 445045ba7..2814c78d3 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -17,20 +17,20 @@ Feature: Test basic usage of login in app | student2 | C1 | student | | teacher1 | C1 | editingteacher | - @app @3.8.0 @OK - Scenario: Add a non existing site + @app @3.8.0 + Scenario: Add a non existing site When I enter the app And I log in as "student1" And I press "menu" in the app And I press "Change site" in the app And I press "add" in the app - And I set the field "Site address" to "Wrong Site Address" in the app - And I press "Connect!" in the app - Then I should see "Error" - And I should see "Double check you've entered the address correctly and try again." + And I set the field "https://campus.example.edu" to "Wrong Site Address" in the app + And I press enter in the app + Then I should see "Cannot connect" + And I should see "Please check the address is correct." - @app @3.8.0 @OK - Scenario: Delete a site + @app @3.8.0 + Scenario: Delete a site When I enter the app And I log in as "student1" And I press "menu" in the app @@ -39,13 +39,12 @@ Feature: Test basic usage of login in app And I press "Delete" in the app And I press "trash" in the app And I press "Delete" in the app - Then I should not see "Acceptance test site" - And I should see "Connect to Moodle" + Then I should see "Connect to Moodle" + But I should not see "Acceptance test site" - @app @3.8.0 @mobile @OK - Scenario: Require minium version of the app for a site and site name in displayed when adding a new site (mobile) + @app @3.8.0 + Scenario: Require minium version of the app for a site and site name in displayed when adding a new site When I enter the app - Then I should see "Acceptance test site" And I log in as "teacher1" And I press "menu" in the app And I press "Website" in the app @@ -58,7 +57,7 @@ Feature: Test basic usage of login in app And I set the field "Minimum app version required" to "3.8.1" And I press "Save changes" And I close the browser tab opened by the app - When I enter the app + And I enter the app And I log in as "teacher1" And I press "menu" in the app And I press "Website" in the app @@ -68,41 +67,8 @@ Feature: Test basic usage of login in app And I press "Side panel" And I follow "Site administration" And I follow "Mobile authentication" - And I set the field "Minimum app version required" to "3.8.2" + And I set the field "Minimum app version required" to "11.0.0" And I press "Save changes" And I close the browser tab opened by the app - When I enter the app + And I enter the app Then I should see "App update required" - - @app @3.8.0 @tablet @OK - Scenario: Require minium version of the app for a site and site name in displayed when adding a new site (tablet) - When I enter the app - And I change viewport size to "1280x1080" - Then I should see "Acceptance test site" - And I log in as "teacher1" - And I press "menu" in the app - And I press "Website" in the app - And I switch to the browser tab opened by the app - And I follow "Log in" - And I log in as "admin" - And I follow "Site administration" - And I follow "Mobile authentication" - And I set the field "Minimum app version required" to "3.8.1" - And I press "Save changes" - And I close the browser tab opened by the app - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "teacher1" - And I press "menu" in the app - And I press "Website" in the app - And I switch to the browser tab opened by the app - And I follow "Log in" - And I log in as "admin" - And I follow "Site administration" - And I follow "Mobile authentication" - And I set the field "Minimum app version required" to "3.8.2" - And I press "Save changes" - And I close the browser tab opened by the app - When I enter the app - And I change viewport size to "1280x1080" - Then I should see "App update required" \ No newline at end of file diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index f887e0f09..2158913ee 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -10,723 +10,395 @@ Feature: Test basic usage of messages in app | teacher1 | Teacher | teacher | teacher1@example.com | | student1 | Student1 | student1 | student1@example.com | | student2 | Student2 | student2 | student2@example.com | - And the following "courses" exist: | fullname | shortname | category | | Course 1 | C1 | 0 | - And the following "course enrolments" exist: | user | course | role | | teacher1 | C1 | editingteacher | | student1 | C1 | student | | student2 | C1 | student | - - @app @3.8.0 @mobile @OK - Scenario: View recent conversations and contacts (mobile) - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - Then I should see "No contacts" - And I press "addon.messages.search" in the app - And I set the field "Search" to "student" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "heeey student" in the app - And I press "Send" in the app - And I press "Conversation actions menu" in the app - And I press "Add to contacts" in the app - And I press "Add" in the app - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - And I press "Requests" in the app - And I press "Teacher teacher" in the app - And I press "Accept and add to contacts" in the app - And I press the back button in the app - And I press "Contacts" near "Requests" in the app - Then the header should be "Contacts" in the app - And I should see "Teacher teacher" - And I press the back button in the app - And I press "Teacher teacher" in the app - Then the header should be "Teacher teacher" in the app - And I should see "heeey student" + @app @3.8.0 + Scenario: View recent conversations and contacts + When I enter the app + And I log in as "teacher1" + And I press "Messages" in the app + And I press "Contacts" in the app + Then I should see "No contacts" - @app @3.8.0 @tablet @OK - Scenario: View recent conversations and contacts (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - Then I should see "No contacts" - And I press "addon.messages.search" in the app - And I set the field "Search" to "student" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "heeey student" in the app - And I press "Send" in the app - And I press "Display options" in the app - And I press "Add to contacts" in the app - And I press "Add" in the app - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - And I press "Requests" in the app - And I press "Teacher teacher" in the app - And I press "Accept and add to contacts" in the app - And I press "Contacts" near "Requests" in the app - Then the header should be "Contacts" in the app - And I should see "Teacher teacher" - And I press the back button in the app - And I press "Teacher teacher" in the app - And I should see "heeey student" + When I press "addon.messages.search" in the app + And I set the field "Search" to "student" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I press "Conversation actions menu" in the app + And I press "Add to contacts" in the app + And I press "Add" in the app - @app @3.8.0 @OK + When I enter the app + And I log in as "student1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "Requests" in the app + And I press "Teacher teacher" in the app + And I press "Accept and add to contacts" in the app + And I press the back button in the app + And I press "Contacts" near "Requests" in the app + Then the header should be "Contacts" in the app + And I should see "Teacher teacher" + + When I press the back button in the app + And I press "Teacher teacher" in the app + Then the header should be "Teacher teacher" in the app + And I should see "heeey student" + + @app @3.8.0 Scenario: Search users - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "addon.messages.search" in the app - And I set the field "Search" to "student2" in the app - And I press "search" in the app - Then I should see "Student2 student2" - And I set the field "Search" to "Teacher" in the app - And I press "search" in the app - Then I should see "Teacher teacher" + When I enter the app + And I log in as "student1" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student2" in the app + And I press "search" in the app + Then I should see "Student2 student2" - @app @3.8.0 @OK + When I set the field "Search" to "Teacher" in the app + And I press "search" in the app + Then I should see "Teacher teacher" + + @app @3.8.0 Scenario: Send/receive messages in existing conversations - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - Then I should see "No contacts" - And I press "addon.messages.search" in the app - And I set the field "Search" to "student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "heeey student" in the app - And I press "Send" in the app - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - Then I should see "No contacts" - And I press "addon.messages.search" in the app - And I set the field "Search" to "teacher" in the app - And I press "search" in the app - And I press "Teacher teacher" in the app - Then I should see "heeey student" - And I set the field "New message" to "hi" in the app - And I press "Send" in the app - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - Then I should see "No contacts" - And I press "addon.messages.search" in the app - And I set the field "Search" to "student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - Then I should see "heeey student" - And I should see "hi" - And I set the field "New message" to "byee" in the app - And I press "Send" in the app - Then I should see "heeey student" - And I should see "hi" - And I should see "byee" + When I enter the app + And I log in as "teacher1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I enter the app + And I log in as "student1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "teacher" in the app + And I press "search" in the app + And I press "Teacher teacher" in the app + Then I should see "heeey student" - @app @3.8.0 @mobile @OK - Scenario: User profile, send message, add/remove contact (mobile) - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - Then I should see "No contacts" - And I press "addon.messages.search" in the app - And I set the field "Search" to "student" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "heeey student" in the app - And I press "Send" in the app - And I press "Conversation actions menu" in the app - And I press "Add to contacts" in the app - And I press "Add" in the app - Then I should see "Contact request sent" - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - And I press "Requests" in the app - And I press "Teacher teacher" in the app - Then I should see "Teacher teacher would like to contact you" - And I press "Accept and add to contacts" in the app - And I should not see "Teacher teacher would like to contact you" - And I press "Teacher teacher" in the app - And I press "Message" in the app - And I set the field "New message" to "hi" in the app - And I press "Send" in the app - Then I should see "heeey student" - And I should see "hi" - And I press the back button in the app - And I press "Remove from contacts" in the app - And I press "Remove" in the app - Then I should see "Add to contacts" - And I press the back button in the app - And I press "Conversation actions menu" in the app - Then I should see "Add to contacts" - And I press "Delete conversation" in the app - And I press "Delete" in the app - And I should not see "heeey student" - And I should not see "hi" + When I set the field "New message" to "hi" in the app + And I press "Send" in the app + And I enter the app + And I log in as "teacher1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + Then I should see "heeey student" + And I should see "hi" + And I set the field "New message" to "byee" in the app + And I press "Send" in the app + Then I should see "heeey student" + And I should see "hi" + And I should see "byee" - @app @3.8.0 @tablet @OK - Scenario: User profile, send message, add/remove contact (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - Then I should see "No contacts" - And I press "addon.messages.search" in the app - And I set the field "Search" to "student" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "heeey student" in the app - And I press "Send" in the app - And I press "Display options" in the app - And I press "Add to contacts" in the app - And I press "Add" in the app - Then I should see "Contact request sent" - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - And I press "Requests" in the app - And I press "Teacher teacher" in the app - Then I should see "Teacher teacher would like to contact you" - And I press "Accept and add to contacts" in the app - And I should not see "Teacher teacher would like to contact you" - And I set the field "New message" to "hi" in the app - And I press "Send" in the app - Then I should see "heeey student" - And I should see "hi" - And I press "Display options" in the app - And I press "Remove from contacts" in the app - And I press "Remove" in the app - And I press "Display options" in the app - Then I should see "Add to contacts" - And I press "Delete conversation" in the app - And I press "Delete" in the app - And I should not see "heeey student" - And I should not see "hi" + @app @3.8.0 + Scenario: User profile, send message, add/remove contact + When I enter the app + And I log in as "teacher1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I press "Conversation actions menu" in the app + And I press "Add to contacts" in the app + And I press "Add" in the app + Then I should see "Contact request sent" - @app @3.8.0 @mobile @OK - Scenario: Send message offline (mobile) - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - Then I should see "No contacts" - And I press "addon.messages.search" in the app - And I set the field "Search" to "student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I switch offline mode to "true" - And I set the field "New message" to "heeey student" in the app - And I press "Send" in the app - And I set the field "New message" to "byee" in the app - And I press "Send" in the app - And I switch offline mode to "false" - And I press the back button in the app - And I press "Student1 student1" in the app - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Teacher teacher" in the app - Then I should see "heeey student" - And I should see "byee" + When I enter the app + And I log in as "student1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "Requests" in the app + And I press "Teacher teacher" in the app + Then I should see "Teacher teacher would like to contact you" - @app @3.8.0 @tablet @OK - Scenario: Send message offline (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - Then I should see "No contacts" - And I press "addon.messages.search" in the app - And I set the field "Search" to "student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I switch offline mode to "true" - And I set the field "New message" to "heeey student" in the app - And I press "Send" in the app - And I set the field "New message" to "byee" in the app - And I press "Send" in the app - And I switch offline mode to "false" - And I press "Student1 student1" in the app - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Teacher teacher" in the app - Then I should see "heeey student" - And I should see "byee" + When I press "Accept and add to contacts" in the app + Then I should not see "Teacher teacher would like to contact you" - @app @3.8.0 @OK + When I press "Teacher teacher" in the app + And I press "Message" in the app + And I set the field "New message" to "hi" in the app + And I press "Send" in the app + Then I should see "heeey student" + And I should see "hi" + + When I press the back button in the app + And I press "Remove from contacts" in the app + And I press "Remove" in the app + Then I should see "Add to contacts" + + When I press the back button in the app + And I press "Conversation actions menu" in the app + Then I should see "Add to contacts" + + When I press "Delete conversation" in the app + And I press "Delete" in the app + And I should not see "heeey student" + And I should not see "hi" + + @app @3.8.0 + Scenario: Send message offline + When I enter the app + And I log in as "teacher1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I switch offline mode to "true" + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I set the field "New message" to "byee" in the app + And I press "Send" in the app + And I switch offline mode to "false" + And I press the back button in the app + And I press "Student1 student1" in the app + And I enter the app + And I log in as "student1" + And I press "Messages" in the app + And I press "Teacher teacher" in the app + Then I should see "heeey student" + And I should see "byee" + + @app @3.8.0 Scenario: Auto-sync messages - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Contacts" in the app - Then I should see "No contacts" - And I press "addon.messages.search" in the app - And I set the field "Search" to "student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I switch offline mode to "true" - And I set the field "New message" to "heeey student" in the app - And I press "Send" in the app - And I set the field "New message" to "byee" in the app - And I press "Send" in the app - And I switch offline mode to "false" - And I wait "600" seconds - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "Teacher teacher" in the app - Then I should see "heeey student" - And I should see "byee" + When I enter the app + And I log in as "teacher1" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I switch offline mode to "true" + And I set the field "New message" to "heeey student" in the app + And I press "Send" in the app + And I set the field "New message" to "byee" in the app + And I press "Send" in the app + And I switch offline mode to "false" + And I run cron tasks in the app + And I enter the app + And I log in as "student1" + And I press "Messages" in the app + And I press "Teacher teacher" in the app + Then I should see "heeey student" + And I should see "byee" - @app @3.8.0 @OK + @app @3.8.0 Scenario: Search for messages - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "addon.messages.search" in the app - And I set the field "Search" to "student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "test message" in the app - And I press "Send" in the app - And I set the field "New message" to "search this message" in the app - And I press "Send" in the app - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "addon.messages.search" in the app - And I set the field "Search" to "search this message" in the app - And I press "search" in the app - Then I should see "Messages" - And I should see "search this message" - And I press "search this message" near "Teacher teacher" in the app - Then I should see "test message" - And I should see "search this message" + When I enter the app + And I log in as "teacher1" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "test message" in the app + And I press "Send" in the app + And I set the field "New message" to "search this message" in the app + And I press "Send" in the app + And I enter the app + And I log in as "student1" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "search this message" in the app + And I press "search" in the app + Then I should see "Messages" + And I should see "search this message" - @app @3.8.0 @mobile @OK - Scenario: Star/Unstar (mobile) - When I enter the app - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "addon.messages.search" in the app - And I set the field "Search" to "student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "star message" in the app - And I press "Send" in the app - When I enter the app - And I log in as "student2" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "addon.messages.search" in the app - And I set the field "Search" to "student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "test message student2" in the app - And I press "Send" in the app - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - Then I should see "Private (2)" - And I should see "Starred (1)" - And I press "star message" in the app - And I press "Conversation actions menu" in the app - And I press "Star conversation" in the app - And I press the back button in the app - Then I should see "Private (1)" - And I should see "Starred (2)" - And I press "Starred (2)" in the app - Then I should see "Teacher teacher" - And I should see "Student1 student1" + When I press "search this message" near "Teacher teacher" in the app + Then I should see "test message" + And I should see "search this message" - @app @3.8.0 @tablet @OK - Scenario: Star/Unstar (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "teacher1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "addon.messages.search" in the app - And I set the field "Search" to "student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "star message" in the app - And I press "Send" in the app - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student2" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - And I press "addon.messages.search" in the app - And I set the field "Search" to "student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "test message student2" in the app - And I press "Send" in the app - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - Then I should see "Private (2)" - And I should see "Starred (1)" - And I press "star message" in the app - And I press "Display options" in the app - And I press "Star conversation" in the app - Then I should see "Private (1)" - And I should see "Starred (2)" - And I press "Starred (2)" in the app - Then I should see "Teacher teacher" - And I should see "Student1 student1" + @app @3.8.0 + Scenario: Star/Unstar + When I enter the app + And I log in as "teacher1" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "star message" in the app + And I press "Send" in the app + And I enter the app + And I log in as "student2" + And I press "Messages" in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "test message student2" in the app + And I press "Send" in the app + And I enter the app + And I log in as "student1" + And I press "Messages" in the app + Then I should see "Private (2)" + And I should see "Starred (1)" - @app @3.8.0 @mobile @OK - Scenario: User blocking feature (mobile) - When I enter the app - And I log in as "student2" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Participants" in the app - And I press "Student1 student1" in the app - Then I should see "Block user" - And I press "Block user" in the app - And I should see "Are you sure you want to block Student1 student1?" - And I press "Cancel" in the app - And I should see "Block user" - And I press "Block user" in the app - And I press "Block user" near "Cancel" in the app - Then I should not see "Block user" - And I should see "Unblock user" - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Participants" in the app - And I press "Student2 student2" in the app - And I press "Message" in the app - Then I should see "You are unable to message this user" - When I enter the app - And I log in as "student2" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Participants" in the app - And I press "Student1 student1" in the app - Then I should see "Unblock user" - And I should not see "Block user" - And I press "Unblock user" in the app - And I press "Cancel" in the app - Then I should see "Unblock user" - And I should not see "Block user" - And I press "Unblock user" in the app - And I press "Unblock user" near "Cancel" in the app - Then I should see "Block user" - And I should not see "Unblock user" - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Participants" in the app - And I press "Student2 student2" in the app - And I press "Message" in the app - And I set the field "New message" to "test message" in the app - And I press "Send" in the app - Then I should see "test message" - And I should not see "You are unable to message this user" + When I press "star message" in the app + And I press "Conversation actions menu" in the app + And I press "Star conversation" in the app + And I press the back button in the app + Then I should see "Private (1)" + And I should see "Starred (2)" - @app @3.8.0 @tablet @OK - Scenario: User blocking feature (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student2" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Participants" in the app - Then I should see "Block user" - And I press "Block user" in the app - And I should see "Are you sure you want to block Student1 student1?" - And I press "Cancel" in the app - And I should see "Block user" - And I press "Block user" in the app - And I press "Block user" near "Cancel" in the app - Then I should not see "Block user" - And I should see "Unblock user" - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Participants" in the app - And I press "Student2 student2" in the app - And I press "Message" in the app - Then I should see "You are unable to message this user" - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student2" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Participants" in the app - Then I should see "Unblock user" - And I should not see "Block user" - And I press "Unblock user" in the app - And I press "Cancel" in the app - Then I should see "Unblock user" - And I should not see "Block user" - And I press "Unblock user" in the app - And I press "Unblock user" near "Cancel" in the app - Then I should see "Block user" - And I should not see "Unblock user" - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Participants" in the app - And I press "Student2 student2" in the app - And I press "Message" in the app - And I set the field "New message" to "test message" in the app - And I press "Send" in the app - Then I should see "test message" - And I should not see "You are unable to message this user" + When I press "Starred (2)" in the app + Then I should see "Teacher teacher" + And I should see "Student1 student1" - @app @3.8.0 @mobile @OK - Scenario: Mute Unmute conversations (mobile) - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Participants" in the app - And I press "Student2 student2" in the app - And I press "Message" in the app - And I set the field "New message" to "test message" in the app - And I press "Send" in the app - And I press "Conversation actions menu" in the app - And I press "Mute" in the app - And I press "Muted conversation" in the app - And I press "Conversation actions menu" in the app - Then I should see "Unmute" - And I should not see "Mute" - And I press "Unmute" in the app - And I press "Conversation actions menu" in the app - Then I should not see "Unmute" - And I should see "Mute" - And I press "Mute" in the app - And I press "Messages" in the app - And I press "Private (1)" in the app - And I press "Student2 student2" in the app - And I press "Conversation actions menu" in the app - Then I should see "Unmute" - And I should not see "Mute" + @app @3.8.0 + Scenario: User blocking feature + When I enter the app + And I log in as "student2" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student1 student1" in the app + And I press "Block user" in the app + And I should see "Are you sure you want to block Student1 student1?" + And I press "Cancel" in the app + And I should see "Block user" + And I press "Block user" in the app + And I press "Block user" near "Cancel" in the app + Then I should see "Unblock user" + But I should not see "Block user" - @app @3.8.0 @tablet @OK - Scenario: Mute Unmute conversations (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Course 1" near "Recently accessed courses" in the app - And I press "Participants" in the app - And I press "Student2 student2" in the app - And I press "Message" in the app - And I set the field "New message" to "test message" in the app - And I press "Send" in the app - And I press "Conversation actions menu" in the app - And I press "Mute" in the app - And I press "Muted conversation" in the app - And I press "Conversation actions menu" in the app - Then I should see "Unmute" - And I should not see "Mute" - And I press "Unmute" in the app - And I press "Conversation actions menu" in the app - Then I should not see "Unmute" - And I should see "Mute" - And I press "Mute" in the app - And I press "Messages" in the app - And I press "Private (1)" in the app - And I press "Student2 student2" in the app - And I press "Display options" in the app - Then I should see "Unmute" - And I should not see "Mute" + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student2 student2" in the app + And I press "Message" in the app + Then I should see "You are unable to message this user" - @app @3.8.0 @mobile @OK - Scenario: Self conversations (mobile) - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - Then I should see "Starred (1)" - And I press "Student1 student1" in the app - And I set the field "New message" to "self conversation" in the app - And I press "Send" in the app - And I switch offline mode to "true" - And I set the field "New message" to "self conversation offline" in the app - And I press "Send" in the app - And I switch offline mode to "false" - And I press the back button in the app - And I press "Student1 student1" in the app - And I press "Conversation actions menu" in the app - Then I should see "Unstar conversation" - And I should see "Show delete messages" - And I should see "Delete conversation" - And I press "Unstar conversation" in the app - And I press "Conversation actions menu" in the app - Then I should see "Star conversation" - And I should see "Show delete messages" - And I should see "Delete conversation" - And I press "Show delete messages" in the app - And I should see "self conversation" - And I should see "self conversation offline" - And I press "Delete message" near "self conversation offline" in the app - And I press "OK" in the app - Then I should see "self conversation" - And I should not see "self conversation offline" - And I press "Conversation actions menu" in the app - And I press "Delete conversation" in the app - And I press "Delete" in the app - Then I should not see "self conversation" - And I should not see "self conversation offline" - And I press the back button in the app - And I press "addon.messages.search" in the app - And I set the field "Search" to "Student1 student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "auto search test" in the app - And I press "Send" in the app - And I press the back button in the app - And I press the back button in the app - And I press "Private" in the app - And I press "Student1 student1" in the app - Then I should see "auto search test" + When I enter the app + And I log in as "student2" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student1 student1" in the app + Then I should see "Unblock user" + But I should not see "Block user" - @app @3.8.0 @tablet @OK - Scenario: Self conversations (tablet) - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I press "Messages" in the app - Then I should see "Starred (1)" - And I press "Student1 student1" in the app - And I set the field "New message" to "self conversation" in the app - And I press "Send" in the app - And I switch offline mode to "true" - And I set the field "New message" to "self conversation offline" in the app - And I press "Send" in the app - And I switch offline mode to "false" - And I press "Student1 student1" in the app - And I press "Display options" in the app - Then I should see "Unstar conversation" - And I should see "Show delete messages" - And I should see "Delete conversation" - And I press "Unstar conversation" in the app - And I press "Display options" in the app - Then I should see "Star conversation" - And I should see "Show delete messages" - And I should see "Delete conversation" - And I press "Show delete messages" in the app - And I should see "self conversation" - And I should see "self conversation offline" - And I press "Delete message" near "self conversation offline" in the app - And I press "OK" in the app - Then I should see "self conversation" - And I should not see "self conversation offline" - And I press "Display options" in the app - And I press "Delete conversation" in the app - And I press "Delete" in the app - Then I should not see "self conversation" - And I should not see "self conversation offline" - And I press "addon.messages.search" in the app - And I set the field "Search" to "Student1 student1" in the app - And I press "search" in the app - And I press "Student1 student1" in the app - And I set the field "New message" to "auto search test" in the app - And I press "Send" in the app - And I press the back button in the app - And I press "Private" in the app - And I press "Student1 student1" in the app - Then I should see "auto search test" \ No newline at end of file + When I press "Unblock user" in the app + And I press "Cancel" in the app + Then I should see "Unblock user" + But I should not see "Block user" + + When I press "Unblock user" in the app + And I press "Unblock user" near "Cancel" in the app + Then I should see "Block user" + But I should not see "Unblock user" + + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student2 student2" in the app + And I press "Message" in the app + And I set the field "New message" to "test message" in the app + And I press "Send" in the app + Then I should see "test message" + But I should not see "You are unable to message this user" + + @app @3.8.0 + Scenario: Mute Unmute conversations + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Recently accessed courses" in the app + And I press "Participants" in the app + And I press "Student2 student2" in the app + And I press "Message" in the app + And I set the field "New message" to "test message" in the app + And I press "Send" in the app + And I press "Conversation actions menu" in the app + And I press "Mute" in the app + And I press "Muted conversation" in the app + And I press "Conversation actions menu" in the app + Then I should not see "Mute" + + When I press "Unmute" in the app + And I press "Conversation actions menu" in the app + Then I should not see "Unmute" + + When I press "Mute" in the app + And I press "Messages" in the app + And I press "Private (1)" in the app + And I press "Student2 student2" in the app + And I press "Conversation actions menu" in the app + Then I should see "Unmute" + But I should not see "Mute" + + @app @3.8.0 + Scenario: Self conversations + When I enter the app + And I log in as "student1" + And I press "Messages" in the app + Then I should see "Starred (1)" + + When I press "Student1 student1" in the app + And I set the field "New message" to "self conversation online" in the app + And I press "Send" in the app + And I switch offline mode to "true" + And I set the field "New message" to "self conversation offline" in the app + And I press "Send" in the app + And I switch offline mode to "false" + And I press the back button in the app + And I press "Student1 student1" in the app + And I press "Conversation actions menu" in the app + Then I should see "Show delete messages" + And I should see "Delete conversation" + + When I press "Unstar conversation" in the app + And I press "Conversation actions menu" in the app + Then I should see "Star conversation" + And I should see "Delete conversation" + + When I press "Show delete messages" in the app + Then I should see "self conversation online" + And I should see "self conversation offline" + + When I press "Delete message" near "self conversation offline" in the app + And I press "OK" in the app + Then I should see "self conversation online" + But I should not see "self conversation offline" + + When I press "Conversation actions menu" in the app + And I press "Delete conversation" in the app + And I press "Delete" in the app + Then I should not see "self conversation online" + And I should not see "self conversation offline" + + When I press the back button in the app + And I press "addon.messages.search" in the app + And I set the field "Search" to "Student1 student1" in the app + And I press "search" in the app + And I press "Student1 student1" in the app + And I set the field "New message" to "auto search test" in the app + And I press "Send" in the app + And I press the back button in the app + And I press the back button in the app + And I press "Private" in the app + And I press "Student1 student1" in the app + Then I should see "auto search test" diff --git a/mod/quiz/tests/behat/app_basic_usage.feature b/mod/quiz/tests/behat/app_basic_usage.feature index 6789cfdd9..263d4d090 100755 --- a/mod/quiz/tests/behat/app_basic_usage.feature +++ b/mod/quiz/tests/behat/app_basic_usage.feature @@ -30,7 +30,6 @@ Feature: Attempt a quiz in app | question | page | | TF1 | 1 | | TF2 | 2 | - And the following "activities" exist: | activity | name | intro | course | idnumber | | quiz | Quiz 2 | Quiz 2 description | C1 | quiz2 | @@ -48,7 +47,7 @@ Feature: Attempt a quiz in app | Test questions | match | TF9 | Text of the seventh question | And quiz "Quiz 2" contains the following questions: | question | page | - | TF3 | 1 | + | TF3 | 1 | | TF4 | 2 | | TF5 | 3 | | TF6 | 4 | @@ -56,40 +55,48 @@ Feature: Attempt a quiz in app | TF8 | 6 | | TF9 | 7 | - - @app @3.8.0 @OK - Scenario: View a quiz entry page (attempts, status, etc.) + @app @3.8.0 + Scenario: View a quiz entry page (attempts, status, etc.) When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Quiz 1" in the app And I press "Attempt quiz now" in the app Then I should see "Text of the first question" - And I should not see "Text of the second question" - And I press "Next" near "Question 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Previous" near "Question 2" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" + But I should not see "Text of the second question" + + When I press "Next" near "Question 1" in the app + Then I should see "Text of the second question" + But I should not see "Text of the first question" + + When I press "Previous" near "Question 2" in the app + Then I should see "Text of the first question" + But I should not see "Text of the second question" + + When I press "Next" near "Quiz 1" in the app + Then I should see "Text of the second question" + But I should not see "Text of the first question" + + When I press "Previous" near "Quiz 1" in the app + Then I should see "Text of the first question" + But I should not see "Text of the second question" + + When I press "Next" near "Question 1" in the app And I press "Next" near "Quiz 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Previous" near "Quiz 1" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" - And I press "Next" near "Question 1" in the app - And I press "Next" near "Quiz 1" in the app - And I should see "Summary of attempt" - And I press "Return to attempt" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Next" in the app + Then I should see "Summary of attempt" + + When I press "Return to attempt" in the app + Then I should see "Text of the second question" + But I should not see "Text of the first question" + + When I press "Next" in the app And I press "Submit all and finish" in the app Then I should see "Once you submit" - And I press "Cancel" near "Once you submit" in the app - And I should see "Summary of attempt" - And I press "Submit all and finish" in the app + + When I press "Cancel" near "Once you submit" in the app + Then I should see "Summary of attempt" + + When I press "Submit all and finish" in the app And I press "OK" near "Once you submit" in the app Then I should see "Review of attempt 1" And I should see "Started on" @@ -101,8 +108,8 @@ Feature: Attempt a quiz in app And I should see "Question 1" And I should see "Question 2" - @app @3.8.0 @OK - Scenario: Attempt a quiz (all question types) + @app @3.8.0 + Scenario: Attempt a quiz (all question types) When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -134,8 +141,8 @@ Feature: Attempt a quiz in app And I should see "Finished" And I should see "Not yet graded" - @app @3.8.0 @OK - Scenario: Submit a quiz and review a quiz attempt + @app @3.8.0 + Scenario: Submit a quiz and review a quiz attempt When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -148,6 +155,7 @@ Feature: Attempt a quiz in app And I press "Submit all and finish" in the app And I press "OK" in the app Then I should see "Review of attempt 1" + When I enter the app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app @@ -160,4 +168,3 @@ Feature: Attempt a quiz in app And I follow "Review attempt" Then I should see "Finished" And I should see "1.00/2.00" - And I close the browser tab opened by the app \ No newline at end of file diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index 12aeb3487..a4b007d0c 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -17,579 +17,382 @@ Feature: Test basic usage of survey activity in app | student1 | C1 | student | | teacher1 | C1 | editingteacher | And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | - | survey | Test survey name | Test survey | C1 | survey | 0 | + | activity | name | intro | course | idnumber | groupmode | + | survey | Test survey name | Test survey | C1 | survey | 0 | - @app @3.8.0 @mobile @OK - Scenario: Student answers a survey ATTLS and see results mobile - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test survey name" in the app - And I press "Choose" near "1. In evaluating what someone says, I focus on the quality of their argument, not on the person who's presenting it." in the app - And I press "Strongly agree" in the app - And I press "Choose" near "2. I like playing devil's advocate - arguing the opposite of what someone is saying." in the app - And I press "Strongly disagree" in the app - And I press "Choose" near "3. I like to understand where other people are 'coming from', what experiences have led them to feel the way they do." in the app - And I press "Somewhat agree" in the app - And I press "Choose" near "4. The most important part of my education has been learning to understand people who are very different to me." in the app - And I press "Somewhat disagree" in the app - And I press "Choose" near "5. I feel that the best way for me to achieve my own identity is to interact with a variety of other people." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "6. I enjoy hearing the opinions of people who come from backgrounds different to mine - it helps me to understand how the same things can be seen in such different ways." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "7. I find that I can strengthen my own position through arguing with someone who disagrees with me." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "8. I am always interested in knowing why people say and believe the things they do." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "9. I often find myself arguing with the authors of books that I read, trying to logically figure out why they're wrong." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "10. It's important for me to remain as objective as possible when I analyze something." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "11. I try to think with people instead of against them." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "12. I have certain criteria I use in evaluating arguments." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "13. I'm more likely to try to understand someone else's opinion than to try to evaluate it." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "14. I try to point out weaknesses in other people's thinking to help them clarify their arguments." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "15. I tend to put myself in other people's shoes when discussing controversial issues, to see why they think the way they do." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "16. One could call my way of analysing things 'putting them on trial' because I am careful to consider all the evidence." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "17. I value the use of logic and reason over the incorporation of my own concerns when solving problems." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "18. I can obtain insight into opinions that differ from mine through empathy." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "19. When I encounter people whose opinions seem alien to me, I make a deliberate effort to 'extend' myself into that person, to try to see how they could have those opinions." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "20. I spend time figuring out what's 'wrong' with things. For example, I'll look for something in a literary interpretation that isn't argued well enough." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Submit" in the app - And I press "OK" in the app - And I press "open" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" + @app @3.8.0 + Scenario: Student answers a survey ATTLS and see results + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey name" in the app + And I press "Choose" near "1. In evaluating what someone says, I focus on the quality of their argument, not on the person who's presenting it." in the app + And I press "Strongly agree" in the app + And I press "Choose" near "2. I like playing devil's advocate - arguing the opposite of what someone is saying." in the app + And I press "Strongly disagree" in the app + And I press "Choose" near "3. I like to understand where other people are 'coming from', what experiences have led them to feel the way they do." in the app + And I press "Somewhat agree" in the app + And I press "Choose" near "4. The most important part of my education has been learning to understand people who are very different to me." in the app + And I press "Somewhat disagree" in the app + And I press "Choose" near "5. I feel that the best way for me to achieve my own identity is to interact with a variety of other people." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "6. I enjoy hearing the opinions of people who come from backgrounds different to mine - it helps me to understand how the same things can be seen in such different ways." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "7. I find that I can strengthen my own position through arguing with someone who disagrees with me." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "8. I am always interested in knowing why people say and believe the things they do." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "9. I often find myself arguing with the authors of books that I read, trying to logically figure out why they're wrong." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "10. It's important for me to remain as objective as possible when I analyze something." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "11. I try to think with people instead of against them." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "12. I have certain criteria I use in evaluating arguments." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "13. I'm more likely to try to understand someone else's opinion than to try to evaluate it." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "14. I try to point out weaknesses in other people's thinking to help them clarify their arguments." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "15. I tend to put myself in other people's shoes when discussing controversial issues, to see why they think the way they do." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "16. One could call my way of analysing things 'putting them on trial' because I am careful to consider all the evidence." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "17. I value the use of logic and reason over the incorporation of my own concerns when solving problems." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "18. I can obtain insight into opinions that differ from mine through empathy." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "19. When I encounter people whose opinions seem alien to me, I make a deliberate effort to 'extend' myself into that person, to try to see how they could have those opinions." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Choose" near "20. I spend time figuring out what's 'wrong' with things. For example, I'll look for something in a literary interpretation that isn't argued well enough." in the app + And I press "Somewhat agree" near "Neither agree nor disagree" in the app + And I press "Submit" in the app + And I press "OK" in the app + And I press "open" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" - @app @3.8.0 @tablet @OK - Scenario: Student answers a survey ATTLS and see results tablet - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test survey name" in the app - And I press "1. In evaluating what someone says, I focus on the quality of their argument, not on the person who's presenting it." in the app - And I press "2. I like playing devil's advocate - arguing the opposite of what someone is saying." in the app - And I press "3. I like to understand where other people are 'coming from', what experiences have led them to feel the way they do." in the app - And I press "4. The most important part of my education has been learning to understand people who are very different to me." in the app - And I press "5. I feel that the best way for me to achieve my own identity is to interact with a variety of other people." in the app - And I press "6. I enjoy hearing the opinions of people who come from backgrounds different to mine - it helps me to understand how the same things can be seen in such different ways." in the app - And I press "7. I find that I can strengthen my own position through arguing with someone who disagrees with me." in the app - And I press "8. I am always interested in knowing why people say and believe the things they do." in the app - And I press "9. I often find myself arguing with the authors of books that I read, trying to logically figure out why they're wrong." in the app - And I press "10. It's important for me to remain as objective as possible when I analyze something." in the app - And I press "11. I try to think with people instead of against them." in the app - And I press "12. I have certain criteria I use in evaluating arguments." in the app - And I press "13. I'm more likely to try to understand someone else's opinion than to try to evaluate it." in the app - And I press "14. I try to point out weaknesses in other people's thinking to help them clarify their arguments." in the app - And I press "15. I tend to put myself in other people's shoes when discussing controversial issues, to see why they think the way they do." in the app - And I press "16. One could call my way of analysing things 'putting them on trial' because I am careful to consider all the evidence." in the app - And I press "17. I value the use of logic and reason over the incorporation of my own concerns when solving problems." in the app - And I press "18. I can obtain insight into opinions that differ from mine through empathy." in the app - And I press "19. When I encounter people whose opinions seem alien to me, I make a deliberate effort to 'extend' myself into that person, to try to see how they could have those opinions." in the app - And I press "20. I spend time figuring out what's 'wrong' with things. For example, I'll look for something in a literary interpretation that isn't argued well enough." in the app - And I press "Submit" in the app - And I press "OK" in the app - And I press "open" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" - - - @app @3.8.0 @OK + @app @3.8.0 Scenario: Student answers a survey of critical incidents and see results - Given the following "activities" exist: - | activity | name | intro | template |course | idnumber | groupmode | - | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test survey critical incidents" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "Results" - And I press "Results" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "Test survey critical incidents" + Given the following "activities" exist: + | activity | name | intro | template |course | idnumber | groupmode | + | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey critical incidents" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "Results" - @app @3.8.0 @mobile @OK - Scenario: Student answers a survey of Colles (actual) and see results mobile - Given the following "activities" exist: - | activity | name | intro | template |course | idnumber | groupmode | - | survey | Test survey Colles (actual) | Test survey1 | 1 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test survey Colles (actual)" in the app - And I press "Choose" near "1. my learning focuses on issues that interest me." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "2. what I learn is important for my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "3. I learn how to improve my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "4. what I learn connects well with my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "5. I think critically about how I learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "6. I think critically about my own ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "7. I think critically about other students' ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "8. I think critically about ideas in the readings." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "9. I explain my ideas to other students." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "10. I ask other students to explain their ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "11. other students ask me to explain my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "12. other students respond to my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "13. the tutor stimulates my thinking." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "14. the tutor encourages me to participate." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "15. the tutor models good discourse." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "16. the tutor models critical self-reflection." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "17. other students encourage my participation." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "18. other students praise my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "19. other students value my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "20. other students empathise with my struggle to learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "21. I make good sense of other students' messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "22. other students make good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "23. I make good sense of the tutor's messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "24. the tutor makes good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "25. How long did this survey take you to complete?" in the app - And I press "under 1 min" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "You have completed this survey" - And I should see "Results" - And I press "Results" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" + When I press "Results" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "Test survey critical incidents" - @app @3.8.0 @tablet @OK - Scenario: Student answers a survey of Colles (actual) and see results tablet - Given the following "activities" exist: - | activity | name | intro | template |course | idnumber | groupmode | - | survey | Test survey Colles (actual) | Test survey1 | 1 | C1 | survey1 | 0 | - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test survey Colles (actual)" in the app - And I press "1. my learning focuses on issues that interest me." in the app - And I press "2. what I learn is important for my professional practice." in the app - And I press "3. I learn how to improve my professional practice." in the app - And I press "4. what I learn connects well with my professional practice." in the app - And I press "5. I think critically about how I learn." in the app - And I press "6. I think critically about my own ideas." in the app - And I press "7. I think critically about other students' ideas." in the app - And I press "8. I think critically about ideas in the readings." in the app - And I press "9. I explain my ideas to other students." in the app - And I press "10. I ask other students to explain their ideas." in the app - And I press "11. other students ask me to explain my ideas." in the app - And I press "12. other students respond to my ideas." in the app - And I press "13. the tutor stimulates my thinking." in the app - And I press "14. the tutor encourages me to participate." in the app - And I press "15. the tutor models good discourse." in the app - And I press "16. the tutor models critical self-reflection." in the app - And I press "17. other students encourage my participation." in the app - And I press "18. other students praise my contribution." in the app - And I press "19. other students value my contribution." in the app - And I press "20. other students empathise with my struggle to learn." in the app - And I press "21. I make good sense of other students' messages." in the app - And I press "22. other students make good sense of my messages." in the app - And I press "23. I make good sense of the tutor's messages." in the app - And I press "24. the tutor makes good sense of my messages." in the app - And I press "25. How long did this survey take you to complete?" in the app - And I press "under 1 min" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "You have completed this survey" - And I should see "Results" - And I press "Results" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" + @app @3.8.0 + Scenario: Student answers a survey of Colles (actual) and see results + Given the following "activities" exist: + | activity | name | intro | template |course | idnumber | groupmode | + | survey | Test survey Colles (actual) | Test survey1 | 1 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey Colles (actual)" in the app + And I press "Choose" near "1. my learning focuses on issues that interest me." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "2. what I learn is important for my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "3. I learn how to improve my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "4. what I learn connects well with my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "5. I think critically about how I learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "6. I think critically about my own ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "7. I think critically about other students' ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "8. I think critically about ideas in the readings." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "9. I explain my ideas to other students." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "10. I ask other students to explain their ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "11. other students ask me to explain my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "12. other students respond to my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "13. the tutor stimulates my thinking." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "14. the tutor encourages me to participate." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "15. the tutor models good discourse." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "16. the tutor models critical self-reflection." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "17. other students encourage my participation." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "18. other students praise my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "19. other students value my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "20. other students empathise with my struggle to learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "21. I make good sense of other students' messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "22. other students make good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "23. I make good sense of the tutor's messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "24. the tutor makes good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "25. How long did this survey take you to complete?" in the app + And I press "under 1 min" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "You have completed this survey" - @app @3.8.0 @mobile @OK - Scenario: Student answers a survey of Colles (preferred) and see results mobile - Given the following "activities" exist: - | activity | name | intro | template |course | idnumber | groupmode | - | survey | Test survey Colles (preferred) | Test survey1 | 2 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test survey Colles (preferred)" in the app - And I press "Choose" near "1. my learning focuses on issues that interest me." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "2. what I learn is important for my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "3. I learn how to improve my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "4. what I learn connects well with my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "5. I think critically about how I learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "6. I think critically about my own ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "7. I think critically about other students' ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "8. I think critically about ideas in the readings." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "9. I explain my ideas to other students." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "10. I ask other students to explain their ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "11. other students ask me to explain my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "12. other students respond to my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "13. the tutor stimulates my thinking." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "14. the tutor encourages me to participate." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "15. the tutor models good discourse." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "16. the tutor models critical self-reflection." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "17. other students encourage my participation." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "18. other students praise my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "19. other students value my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "20. other students empathise with my struggle to learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "21. I make good sense of other students' messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "22. other students make good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "23. I make good sense of the tutor's messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "24. the tutor makes good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "25. How long did this survey take you to complete?" in the app - And I press "under 1 min" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "You have completed this survey" - And I should see "Results" - And I press "Results" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" + When I press "Results" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" - @app @3.8.0 @tablet @OK - Scenario: Student answers a survey of Colles (preferred) and see results tablet - Given the following "activities" exist: - | activity | name | intro | template |course | idnumber | groupmode | - | survey | Test survey Colles (preferred) | Test survey1 | 2 | C1 | survey1 | 0 | - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test survey Colles (preferred)" in the app - And I press "1. my learning focuses on issues that interest me." in the app - And I press "2. what I learn is important for my professional practice." in the app - And I press "3. I learn how to improve my professional practice." in the app - And I press "4. what I learn connects well with my professional practice." in the app - And I press "5. I think critically about how I learn." in the app - And I press "6. I think critically about my own ideas." in the app - And I press "7. I think critically about other students' ideas." in the app - And I press "8. I think critically about ideas in the readings." in the app - And I press "9. I explain my ideas to other students." in the app - And I press "10. I ask other students to explain their ideas." in the app - And I press "11. other students ask me to explain my ideas." in the app - And I press "12. other students respond to my ideas." in the app - And I press "13. the tutor stimulates my thinking." in the app - And I press "14. the tutor encourages me to participate." in the app - And I press "15. the tutor models good discourse." in the app - And I press "16. the tutor models critical self-reflection." in the app - And I press "17. other students encourage my participation." in the app - And I press "18. other students praise my contribution." in the app - And I press "19. other students value my contribution." in the app - And I press "20. other students empathise with my struggle to learn." in the app - And I press "21. I make good sense of other students' messages." in the app - And I press "22. other students make good sense of my messages." in the app - And I press "23. I make good sense of the tutor's messages." in the app - And I press "24. the tutor makes good sense of my messages." in the app - And I press "25. How long did this survey take you to complete?" in the app - And I press "under 1 min" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "You have completed this survey" - And I should see "Results" - And I press "Results" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" + @app @3.8.0 + Scenario: Student answers a survey of Colles (preferred) and see results + Given the following "activities" exist: + | activity | name | intro | template | course | idnumber | groupmode | + | survey | Test survey Colles (preferred) | Test survey1 | 2 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey Colles (preferred)" in the app + And I press "Choose" near "1. my learning focuses on issues that interest me." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "2. what I learn is important for my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "3. I learn how to improve my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "4. what I learn connects well with my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "5. I think critically about how I learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "6. I think critically about my own ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "7. I think critically about other students' ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "8. I think critically about ideas in the readings." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "9. I explain my ideas to other students." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "10. I ask other students to explain their ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "11. other students ask me to explain my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "12. other students respond to my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "13. the tutor stimulates my thinking." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "14. the tutor encourages me to participate." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "15. the tutor models good discourse." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "16. the tutor models critical self-reflection." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "17. other students encourage my participation." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "18. other students praise my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "19. other students value my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "20. other students empathise with my struggle to learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "21. I make good sense of other students' messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "22. other students make good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "23. I make good sense of the tutor's messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "24. the tutor makes good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "25. How long did this survey take you to complete?" in the app + And I press "under 1 min" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "You have completed this survey" + When I press "Results" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" + @app @3.8.0 + Scenario: Student answers a survey of Colles (preferred and actual) and see results + Given the following "activities" exist: + | activity | name | intro | template | course | idnumber | groupmode | + | survey | Test survey Colles (preferred and actual) | Test survey1 | 3 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey Colles (preferred and actual)" in the app + And I press "Choose" near "1. I prefer that my learning focuses on issues that interest me." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "2. I found that my learning focuses on issues that interest me." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "3. I prefer that what I learn is important for my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "4. I found that what I learn is important for my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "5. I prefer that I learn how to improve my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "6. I found that I learn how to improve my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "7. I prefer that what I learn connects well with my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "8. I found that what I learn connects well with my professional practice." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "9. I prefer that I think critically about how I learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "10. I found that I think critically about how I learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "11. I prefer that I think critically about my own ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "12. I found that I think critically about my own ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "13. I prefer that I think critically about other students' ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "14. I found that I think critically about other students' ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "15. I prefer that I think critically about ideas in the readings." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "16. I found that I think critically about ideas in the readings." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "17. I prefer that I explain my ideas to other students." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "18. I found that I explain my ideas to other students." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "19. I prefer that I ask other students to explain their ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "20. I found that I ask other students to explain their ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "21. I prefer that other students ask me to explain my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "22. I found that other students ask me to explain my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "23. I prefer that other students respond to my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "24. I found that other students respond to my ideas." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "25. I prefer that the tutor stimulates my thinking." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "26. I found that the tutor stimulates my thinking." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "27. I prefer that the tutor encourages me to participate." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "28. I found that the tutor encourages me to participate." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "29. I prefer that the tutor models good discourse." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "30. I found that the tutor models good discourse." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "31. I prefer that the tutor models critical self-reflection." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "32. I found that the tutor models critical self-reflection." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "33. I prefer that other students encourage my participation." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "34. I found that other students encourage my participation." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "35. I prefer that other students praise my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "36. I found that other students praise my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "37. I prefer that other students value my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "38. I found that other students value my contribution." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "39. I prefer that other students empathise with my struggle to learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "40. I found that other students empathise with my struggle to learn." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "41. I prefer that I make good sense of other students' messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "42. I found that I make good sense of other students' messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "43. I prefer that other students make good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "44. I found that other students make good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "45. I prefer that I make good sense of the tutor's messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "46. I found that I make good sense of the tutor's messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "47. I prefer that the tutor makes good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "48. I found that the tutor makes good sense of my messages." in the app + And I press "Sometimes" near "Often" in the app + And I press "Choose" near "49. How long did this survey take you to complete?" in the app + And I press "1-2 min" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "You have completed this survey" - @app @3.8.0 @mobile @OK - Scenario: Student answers a survey of Colles (preferred and actual) and see results mobile - Given the following "activities" exist: - | activity | name | intro | template |course | idnumber | groupmode | - | survey | Test survey Colles (preferred and actual) | Test survey1 | 3 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test survey Colles (preferred and actual)" in the app - And I press "Choose" near "1. I prefer that my learning focuses on issues that interest me." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "2. I found that my learning focuses on issues that interest me." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "3. I prefer that what I learn is important for my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "4. I found that what I learn is important for my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "5. I prefer that I learn how to improve my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "6. I found that I learn how to improve my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "7. I prefer that what I learn connects well with my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "8. I found that what I learn connects well with my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "9. I prefer that I think critically about how I learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "10. I found that I think critically about how I learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "11. I prefer that I think critically about my own ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "12. I found that I think critically about my own ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "13. I prefer that I think critically about other students' ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "14. I found that I think critically about other students' ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "15. I prefer that I think critically about ideas in the readings." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "16. I found that I think critically about ideas in the readings." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "17. I prefer that I explain my ideas to other students." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "18. I found that I explain my ideas to other students." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "19. I prefer that I ask other students to explain their ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "20. I found that I ask other students to explain their ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "21. I prefer that other students ask me to explain my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "22. I found that other students ask me to explain my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "23. I prefer that other students respond to my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "24. I found that other students respond to my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "25. I prefer that the tutor stimulates my thinking." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "26. I found that the tutor stimulates my thinking." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "27. I prefer that the tutor encourages me to participate." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "28. I found that the tutor encourages me to participate." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "29. I prefer that the tutor models good discourse." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "30. I found that the tutor models good discourse." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "31. I prefer that the tutor models critical self-reflection." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "32. I found that the tutor models critical self-reflection." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "33. I prefer that other students encourage my participation." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "34. I found that other students encourage my participation." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "35. I prefer that other students praise my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "36. I found that other students praise my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "37. I prefer that other students value my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "38. I found that other students value my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "39. I prefer that other students empathise with my struggle to learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "40. I found that other students empathise with my struggle to learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "41. I prefer that I make good sense of other students' messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "42. I found that I make good sense of other students' messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "43. I prefer that other students make good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "44. I found that other students make good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "45. I prefer that I make good sense of the tutor's messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "46. I found that I make good sense of the tutor's messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "47. I prefer that the tutor makes good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "48. I found that the tutor makes good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "49. How long did this survey take you to complete?" in the app - And I press "1-2 min" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "You have completed this survey" - And I should see "Results" - And I press "Results" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" + When I press "Results" in the app + And I switch to the browser tab opened by the app + And I log in as "student1" + Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." + And I should see "1 people have completed this survey so far" - - @app @3.8.0 @tablet @OK - Scenario: Student answers a survey of Colles (preferred and actual) and see results tablet - Given the following "activities" exist: - | activity | name | intro | template |course | idnumber | groupmode | - | survey | Test survey Colles (preferred and actual) | Test survey1 | 3 | C1 | survey1 | 0 | - When I enter the app - And I change viewport size to "1280x1080" - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test survey Colles (preferred and actual)" in the app - And I press "1. I prefer that my learning focuses on issues that interest me." in the app - And I press "2. I found that my learning focuses on issues that interest me." in the app - And I press "3. I prefer that what I learn is important for my professional practice." in the app - And I press "4. I found that what I learn is important for my professional practice." in the app - And I press "5. I prefer that I learn how to improve my professional practice." in the app - And I press "6. I found that I learn how to improve my professional practice." in the app - And I press "7. I prefer that what I learn connects well with my professional practice." in the app - And I press "8. I found that what I learn connects well with my professional practice." in the app - And I press "9. I prefer that I think critically about how I learn." in the app - And I press "10. I found that I think critically about how I learn." in the app - And I press "11. I prefer that I think critically about my own ideas." in the app - And I press "12. I found that I think critically about my own ideas." in the app - And I press "13. I prefer that I think critically about other students' ideas." in the app - And I press "14. I found that I think critically about other students' ideas." in the app - And I press "15. I prefer that I think critically about ideas in the readings." in the app - And I press "16. I found that I think critically about ideas in the readings." in the app - And I press "17. I prefer that I explain my ideas to other students." in the app - And I press "18. I found that I explain my ideas to other students." in the app - And I press "19. I prefer that I ask other students to explain their ideas." in the app - And I press "20. I found that I ask other students to explain their ideas." in the app - And I press "21. I prefer that other students ask me to explain my ideas." in the app - And I press "22. I found that other students ask me to explain my ideas." in the app - And I press "23. I prefer that other students respond to my ideas." in the app - And I press "24. I found that other students respond to my ideas." in the app - And I press "25. I prefer that the tutor stimulates my thinking." in the app - And I press "26. I found that the tutor stimulates my thinking." in the app - And I press "27. I prefer that the tutor encourages me to participate." in the app - And I press "28. I found that the tutor encourages me to participate." in the app - And I press "29. I prefer that the tutor models good discourse." in the app - And I press "30. I found that the tutor models good discourse." in the app - And I press "31. I prefer that the tutor models critical self-reflection." in the app - And I press "32. I found that the tutor models critical self-reflection." in the app - And I press "33. I prefer that other students encourage my participation." in the app - And I press "34. I found that other students encourage my participation." in the app - And I press "35. I prefer that other students praise my contribution." in the app - And I press "36. I found that other students praise my contribution." in the app - And I press "37. I prefer that other students value my contribution." in the app - And I press "38. I found that other students value my contribution." in the app - And I press "39. I prefer that other students empathise with my struggle to learn." in the app - And I press "40. I found that other students empathise with my struggle to learn." in the app - And I press "41. I prefer that I make good sense of other students' messages." in the app - And I press "42. I found that I make good sense of other students' messages." in the app - And I press "43. I prefer that other students make good sense of my messages." in the app - And I press "44. I found that other students make good sense of my messages." in the app - And I press "45. I prefer that I make good sense of the tutor's messages." in the app - And I press "46. I found that I make good sense of the tutor's messages." in the app - And I press "47. I prefer that the tutor makes good sense of my messages." in the app - And I press "48. I found that the tutor makes good sense of my messages." in the app - And I press "49. How long did this survey take you to complete?" in the app - And I press "1-2 min" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "You have completed this survey" - And I should see "Results" - And I press "Results" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" - - @app @3.8.0 @OK + @app @3.8.0 Scenario: Student answers a survey offline and sync survey - Given the following "activities" exist: - | activity | name | intro | template |course | idnumber | groupmode | - | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test survey critical incidents" in the app - And I switch offline mode to "true" - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "This Survey has offline data to be synchronised." - And I switch offline mode to "false" - And I press the back button in the app - And I press "Test survey critical incidents" in the app - And I press "Display options" in the app - And I press "Refresh" in the app - Then I should see "Results" - And I should not see "This Survey has offline data to be synchronised." - And I should see "You have completed this survey." + Given the following "activities" exist: + | activity | name | intro | template | course | idnumber | groupmode | + | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test survey critical incidents" in the app + And I switch offline mode to "true" + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "This Survey has offline data to be synchronised." - @app @3.8.0 @OK + When I switch offline mode to "false" + And I press the back button in the app + And I press "Test survey critical incidents" in the app + And I press "Display options" in the app + And I press "Refresh" in the app + Then I should see "Results" + And I should see "You have completed this survey." + But I should not see "This Survey has offline data to be synchronised." + + @app @3.8.0 Scenario: Prefetch and auto-sync - Given the following "activities" exist: - | activity | name | intro | template |course | idnumber | groupmode | - | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Display options" in the app - And I press "Show download options" in the app - And I press "cloud download" near "Test survey critical incidents" in the app - And I switch offline mode to "true" - And I press "Test survey name" in the app - Then I should see "There was a problem connecting to the site. Please check your connection and try again." - And I press "OK" in the app - And I press the back button in the app - And I press "Test survey critical incidents" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "This Survey has offline data to be synchronised." - And I switch offline mode to "false" - And I wait "600" seconds - Then I should not see "This Survey has offline data to be synchronised." - And I should see "You have completed this survey." \ No newline at end of file + Given the following "activities" exist: + | activity | name | intro | template | course | idnumber | groupmode | + | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Display options" in the app + And I press "Show download options" in the app + And I press "cloud download" near "Test survey critical incidents" in the app + And I switch offline mode to "true" + And I press "Test survey name" in the app + Then I should see "There was a problem connecting to the site. Please check your connection and try again." + + When I press "OK" in the app + And I press the back button in the app + And I press "Test survey critical incidents" in the app + And I press "Submit" in the app + And I press "OK" in the app + Then I should see "This Survey has offline data to be synchronised." + + When I switch offline mode to "false" + And I run cron tasks in the app + Then I should not see "This Survey has offline data to be synchronised." + And I should see "You have completed this survey." diff --git a/tests/behat/behat_local_moodlemobileapp.php b/tests/behat/behat_local_moodlemobileapp.php new file mode 100644 index 000000000..63e04ee2a --- /dev/null +++ b/tests/behat/behat_local_moodlemobileapp.php @@ -0,0 +1,100 @@ +. + +/** + * Behat step definitions. + * + * @package local_apps + * @copyright 2010 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use Behat\Mink\Exception\ExpectationException; + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../../../lib/behat/behat_base.php'); + +/** + * Behat step definitions. + * + * @package local_apps + * @copyright 2010 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_local_moodlemobileapp extends behat_base { + + /** + * Force cron tasks instead of waiting for the next scheduled execution. + * + * @When /^I run cron tasks in the app$/ + */ + public function i_run_cron_tasks_in_the_app() { + $session = $this->getSession(); + + // Force cron tasks execution and wait until they are completed. + $operationid = random_string(); + + $session->evaluateScript( + "cronProvider.forceSyncExecution().then(() => { window['behat_{$operationid}_completed'] = true; });" + ); + $this->spin( + function() use ($session, $operationid) { + return $session->evaluateScript("window['behat_{$operationid}_completed'] || false"); + }, + false, + 60, + new ExpectationException('Forced cron tasks in the app took too long to complete', $session) + ); + + // Trigger Angular digest cycle multiple times in case some changes have + // side-effects that result in further pending operations. + for ($ticks = 5; $ticks > 0; $ticks--) { + $session->evaluateScript('appRef.tick();'); + } + } + + /** + * Wait until loading has finished. + * + * @When /^I wait loading to finish in the app$/ + */ + public function i_wait_loading_to_finish_in_the_app() { + $session = $this->getSession(); + + $this->spin( + function() use ($session) { + $session->evaluateScript('appRef.tick();'); + + $nodes = $this->find_all('css', 'core-loading ion-spinner'); + + foreach ($nodes as $node) { + if (!$node->isVisible()) { + continue; + } + + return false; + } + + return true; + }, + false, + 60, + new ExpectationException('"Loading took too long to complete', $session) + ); + } + +} From ff2ffeb0771522c3689f869c1f01e89b405f6d52 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 15 Jun 2020 17:11:16 +0200 Subject: [PATCH 090/220] MOBILE-3294: Update definitions to match testing document --- .../tests/behat/app_basic_usage.feature | 6 ++-- mod/chat/tests/behat/app_basic_usage.feature | 4 +-- .../tests/behat/app_basic_usage.feature | 10 +++--- .../tests/behat/app_basic_usage.feature | 12 +++---- .../tests/behat/app_basic_usage.feature | 4 +-- .../tests/behat/app_course_completion.feature | 2 +- mod/course/tests/behat/app_courselist.feature | 31 +++++-------------- .../tests/behat/app_basic_usage.feature | 2 +- mod/data/tests/behat/app_data_entries.feature | 8 ++--- mod/data/tests/behat/app_data_sync.feature | 4 +-- mod/forum/tests/behat/app_basic_usage.feature | 16 +++++----- mod/login/tests/behat/app_basic_usage.feature | 16 +++++++++- .../tests/behat/app_basic_usage.feature | 2 +- mod/quiz/tests/behat/app_basic_usage.feature | 2 +- .../tests/behat/app_quiz_navigation.feature | 2 +- .../tests/behat/app_basic_usage.feature | 24 +++++++++----- 16 files changed, 76 insertions(+), 69 deletions(-) diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index 775a0319c..1bfb70b57 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -20,7 +20,7 @@ Feature: Test basic usage of assignment activity in app | assign | C1 | assign1 | assignment1 | Test assignment description1 | 1 | 1029844800 | manual | @app @3.8.0 - Scenario: Create, edit and submit an assignment as a student, view it as a teacher + Scenario: View assign description, due date & View list of student submissions (as teacher) & View own submission or student submission # Create, edit and submit as a student When I enter the app And I log in as "student1" @@ -65,7 +65,7 @@ Feature: Test basic usage of assignment activity in app And I should see "Submission test edited" @app @3.8.0 - Scenario: Add new attempt from previous submission + Scenario: Edit/Add submission (online text) & Add new attempt from previous submission & Submit for grading # Submit first attempt as a student Given I enter the app And I log in as "student1" @@ -121,7 +121,7 @@ Feature: Test basic usage of assignment activity in app And I should see "Submission test 2nd attempt" @app @3.8.0 - Scenario: Add offline submission and synchronise it + Scenario: Add submission offline (online text) & Submit for grading offline & Sync submissions When I enter the app And I log in as "student1" And I press "Course 1" near "Recently accessed courses" in the app diff --git a/mod/chat/tests/behat/app_basic_usage.feature b/mod/chat/tests/behat/app_basic_usage.feature index 725287ea6..424c80051 100755 --- a/mod/chat/tests/behat/app_basic_usage.feature +++ b/mod/chat/tests/behat/app_basic_usage.feature @@ -20,7 +20,7 @@ Feature: Test basic usage of chat in app | chat | Test chat name | Test chat | C1 | chat | 0 | @app @3.8.0 - Scenario: Send and read messages, send beeps and view connected users + Scenario: Receive and send messages & See connected users, beep and talk to # Send messages as student1 When I enter the app And I log in as "student1" @@ -57,7 +57,7 @@ Feature: Test basic usage of chat in app Then I should see "Hi David, I am Pau." @app @3.8.0 - Scenario: View past sessions shown for >=3.5 + Scenario: Past sessions shown for >=3.5 # Send messages as student1 Given I enter the app And I log in as "student1" diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 30c30c48a..74cfd7429 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -18,7 +18,7 @@ Feature: Test basic usage of choice activity in app | student1 | C1 | student | @app @3.8.0 - Scenario: Student sends a single choice answer and views the results + Scenario: Answer a choice (multi or single, update answer) & View results Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | @@ -44,7 +44,7 @@ Feature: Test basic usage of choice activity in app And I should see "Option 3: 0" @app @3.8.0 - Scenario: Student sends, changes and removes a multi choice answer + Scenario: Answer a choice (multi or single, update answer) & View results & Delete choice Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | @@ -75,7 +75,7 @@ Feature: Test basic usage of choice activity in app But I should not see "Remove my choice" @app @3.8.0 - Scenario: Student edits answer offline and synchronises + Scenario: Answer and change answer offline & Sync choice Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | @@ -108,7 +108,7 @@ Feature: Test basic usage of choice activity in app But I should not see "This Choice has offline data to be synchronised." @app @3.8.0 - Scenario: Student edits answer offline and the app synchronises automatically + Scenario: Answer and change answer offline & Auto-sync choice Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | @@ -136,7 +136,7 @@ Feature: Test basic usage of choice activity in app But I should not see "This Choice has offline data to be synchronised." @app @3.8.0 - Scenario: Prefetch activity + Scenario: Prefetch Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | diff --git a/mod/comments/tests/behat/app_basic_usage.feature b/mod/comments/tests/behat/app_basic_usage.feature index 36ad7cd4a..e4066d82d 100755 --- a/mod/comments/tests/behat/app_basic_usage.feature +++ b/mod/comments/tests/behat/app_basic_usage.feature @@ -24,7 +24,7 @@ Feature: Test basic usage of comments in app | data | Data | Data info | C1 | data1 | 1 | @app @3.8.0 - Scenario: Create and delete comments (database) + Scenario: Add comments & Delete comments (database) # Create database entry and comment as a teacher Given I enter the app And I log in as "teacher1" @@ -84,7 +84,7 @@ Feature: Test basic usage of comments in app Then I should see "Comments (1)" @app @3.8.0 - Scenario: Create and delete offline comments and synchronise (database) + Scenario: Add comments offline & Delete comments offline & Sync comments (database) Given I enter the app And I log in as "teacher1" And I press "Course 1" near "Recently accessed courses" in the app @@ -146,7 +146,7 @@ Feature: Test basic usage of comments in app And I should see "Comments (0)" @app @3.8.0 - Scenario: Create and delete comments (glossary) + Scenario: Add comments & delete comments (glossary) # Create glossary entry and comment as a teacher When I enter the app And I log in as "teacher1" @@ -193,7 +193,7 @@ Feature: Test basic usage of comments in app And I should see "Comments (1)" @app @3.8.0 - Scenario: Create and delete offline comments and synchronise (glossary) + Scenario: Add comments offline & Delete comments offline & Sync comments (glossary) When I enter the app And I log in as "teacher1" And I press "Course 1" near "Recently accessed courses" in the app @@ -243,7 +243,7 @@ Feature: Test basic usage of comments in app And I should see "Comments (0)" @app @3.8.0 - Scenario: Create and delete comments (blogs) + Scenario: Add comments & Delete comments (blogs) # Create blog as a teacher Given I enter the app And I log in as "teacher1" @@ -293,7 +293,7 @@ Feature: Test basic usage of comments in app Then I should see "Comments (0)" @app @3.8.0 - Scenario: Create and delete offline comments and synchronise (blogs) + Scenario: Add comments offline & Delete comments offline & Sync comments (blogs) # Create blog as a teacher Given I enter the app And I log in as "teacher1" diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 622ae2bfd..0e66729d6 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -72,7 +72,7 @@ Feature: Test basic usage of one course in app | workshop | Test workshop name | Test workshop | C1 | workshop | 0 | 3 | @app @3.8.0 - Scenario: Student views course contents + Scenario: View course contents When I enter the app And I log in as "student1" And I press "Course 1" near "Recently accessed courses" in the app @@ -150,7 +150,7 @@ Feature: Test basic usage of one course in app Then the header should be "Test workshop name" in the app @app @3.8.0 - Scenario: Student views section contents + Scenario: View section contents When I enter the app And I log in as "student1" And I press "Course 1" near "Recently accessed courses" in the app diff --git a/mod/course/tests/behat/app_course_completion.feature b/mod/course/tests/behat/app_course_completion.feature index f0c30baa9..a3c2475a5 100644 --- a/mod/course/tests/behat/app_course_completion.feature +++ b/mod/course/tests/behat/app_course_completion.feature @@ -15,7 +15,7 @@ Feature: Check course completion feature. | user | course | role | | student1 | C1 | student | - Scenario: Complete the activity manually by clicking at the completion checkbox. + Scenario: Activity completion, marking the checkbox manually Given the following "activities" exist: | activity | name | course | idnumber | completion | completionview | | forum | First forum | C1 | forum1 | 1 | 0 | diff --git a/mod/course/tests/behat/app_courselist.feature b/mod/course/tests/behat/app_courselist.feature index 70d8b6606..1e1bc1e1f 100644 --- a/mod/course/tests/behat/app_courselist.feature +++ b/mod/course/tests/behat/app_courselist.feature @@ -19,39 +19,22 @@ Feature: Test course list shown on app start tab | student2 | C1 | student | | student2 | C2 | student | - Scenario: Student is registered on one course + Scenario: View courses (shortnames not displayed) When I enter the app And I log in as "student1" Then I should see "Course 1" - And I should not see "Course 2" + But I should not see "Course 2" + But I should not see "C1" + But I should not see "C2" - Scenario: Student is registered on two courses (shortnames not displayed) When I enter the app And I log in as "student2" Then I should see "Course 1" And I should see "Course 2" - And I should not see "C1" - And I should not see "C2" + But I should not see "C1" + But I should not see "C2" - Scenario: Student is registered on two courses (shortnames displayed) - Given the following config values are set as admin: - | courselistshortnames | 1 | - When I enter the app - And I log in as "student2" - Then I should see "Course 1" - And I should see "Course 2" - And I should see "C1" - And I should see "C2" - - Scenario: Student uses course list to enter course, then leaves it again - When I enter the app - And I log in as "student2" - And I press "Course 2" near "Course overview" in the app - Then the header should be "Course 2" in the app - And I press the back button in the app - Then the header should be "Acceptance test site" in the app - - Scenario: Student uses filter feature to reduce course list + Scenario: Filter courses Given the following config values are set as admin: | courselistshortnames | 1 | And the following "courses" exist: diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index fc5c12cd9..fea9ce84a 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -35,7 +35,7 @@ Feature: Test basic usage of courses in app | assign | C1 | assign1 | assignment | Test assignment description | 1 | @app @3.8.0 - Scenario: Dashboard tab displayed in >= 3.3 sites + Scenario: "Dashboard" tab displayed in >= 3.3 sites When I enter the app And I log in as "student1" Then I should see "Dashboard" diff --git a/mod/data/tests/behat/app_data_entries.feature b/mod/data/tests/behat/app_data_entries.feature index b7765f2c6..41e8ad6c5 100644 --- a/mod/data/tests/behat/app_data_entries.feature +++ b/mod/data/tests/behat/app_data_entries.feature @@ -31,7 +31,7 @@ Feature: Users can manage entries in database activities | Field description | Link description | And I log out - Scenario: Students can add entries to a database in the app + Scenario: Create entry Given I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -44,7 +44,7 @@ Feature: Users can manage entries in database activities Then I should see "https://moodle.org/" And I should see "Moodle community site" - Scenario: Students can navigate along single entries in the app + Scenario: Browse entry Given I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -95,7 +95,7 @@ Feature: Users can manage entries in database activities And "Edit" "link" should not exist And "Delete" "link" should not exist - Scenario: Students can edit and delete their own entries from list and single view in the app + Scenario: Delete entry (student) & Update entry (student) Given I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -143,7 +143,7 @@ Feature: Users can manage entries in database activities And I should not see "Moodle Cloud" And I should see "No entries in database" - Scenario: Teachers can edit and delete students' entries from list view in the app + Scenario: Delete entry (teacher) & Update entry (teacher) Given I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app diff --git a/mod/data/tests/behat/app_data_sync.feature b/mod/data/tests/behat/app_data_sync.feature index 274132587..f0b147b95 100644 --- a/mod/data/tests/behat/app_data_sync.feature +++ b/mod/data/tests/behat/app_data_sync.feature @@ -32,7 +32,7 @@ Feature: Users can store entries in database activities when offline and sync wh And I log out @app_from3.7 - Scenario: Students can add entries to a database in the app while offline + Scenario: Create entry (offline) Given I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -54,7 +54,7 @@ Feature: Users can store entries in database activities when offline and sync wh And I should not see "This Database has offline data to be synchronised" @app_from3.7 - Scenario: Students can edit and delete entries to a database in the app while offline + Scenario: Update entry (offline) & Delete entry (offline) Given I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 6484fa0dc..f3b4fd883 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -25,7 +25,7 @@ Feature: Test basic usage of forum activity in app | forum | Test forum name | Test forum | C1 | forum | 0 | 1 | 1 | @app @3.8.0 - Scenario: Student starts a discussion + Scenario: Create new discussion When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -40,7 +40,7 @@ Feature: Test basic usage of forum activity in app Then I should see "An awesome message" @app_from3.7 - Scenario: Student posts a reply + Scenario: Reply a post When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -57,7 +57,7 @@ Feature: Test basic usage of forum activity in app And I should see "ReplyMessage" @app @3.8.0 - Scenario: Student stars a discussion + Scenario: Star and pin discussions (student) When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -94,7 +94,7 @@ Feature: Test basic usage of forum activity in app Then I should see "normal message" @app @3.8.0 - Scenario: Teacher star and pin a discussion + Scenario: Star and pin discussions (teacher) When I enter the app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app @@ -127,7 +127,7 @@ Feature: Test basic usage of forum activity in app And I should see "Auto-test pin" @app_upto3.6.0 - Scenario: Teacher checks pin and star in 3.6 + Scenario: Star and pin discussions (teacher in 3.6) When I enter the app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app @@ -313,7 +313,7 @@ Feature: Test basic usage of forum activity in app But I should not see "Average of ratings: -" @app @3.8.0 - Scenario: Student replies a post offline + Scenario: Reply a post offline When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -344,7 +344,7 @@ Feature: Test basic usage of forum activity in app But I should not see "Not sent" @app @3.8.0 - Scenario: Student creates a new discussion offline and sync forum + Scenario: New discussion offline & Sync Forum When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -370,7 +370,7 @@ Feature: Test basic usage of forum activity in app And I should not see "This Forum has offline data to be synchronised." @app @3.8.0 - Scenario: Student creates a new discussion offline and auto-sync forum + Scenario: New discussion offline & Auto-sync forum When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index 2814c78d3..4321f9ca9 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -17,6 +17,20 @@ Feature: Test basic usage of login in app | student2 | C1 | student | | teacher1 | C1 | editingteacher | + @app @3.8.0 + Scenario: Add a new site in the app & Site name in displayed when adding a new site + When I enter the app + And I press the back button in the app + And I set the field "https://campus.example.edu" to "webserver" in the app + And I press "Connect to your site" in the app + Then I should see "Acceptance test site" + + When I set the field "Username" to "student1" in the app + And I set the field "Password" to "student1" in the app + And I press "Log in" near "Forgotten your username or password?" in the app + Then I should see "Acceptance test site" + But I should not see "Log in" + @app @3.8.0 Scenario: Add a non existing site When I enter the app @@ -43,7 +57,7 @@ Feature: Test basic usage of login in app But I should not see "Acceptance test site" @app @3.8.0 - Scenario: Require minium version of the app for a site and site name in displayed when adding a new site + Scenario: Require minium version of the app for a site When I enter the app And I log in as "teacher1" And I press "menu" in the app diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index 2158913ee..f33f06c13 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -109,7 +109,7 @@ Feature: Test basic usage of messages in app And I should see "byee" @app @3.8.0 - Scenario: User profile, send message, add/remove contact + Scenario: User profile: send message, add/remove contact When I enter the app And I log in as "teacher1" And I press "Messages" in the app diff --git a/mod/quiz/tests/behat/app_basic_usage.feature b/mod/quiz/tests/behat/app_basic_usage.feature index 263d4d090..ca652fdcb 100755 --- a/mod/quiz/tests/behat/app_basic_usage.feature +++ b/mod/quiz/tests/behat/app_basic_usage.feature @@ -142,7 +142,7 @@ Feature: Attempt a quiz in app And I should see "Not yet graded" @app @3.8.0 - Scenario: Submit a quiz and review a quiz attempt + Scenario: Submit a quiz & Review a quiz attempt When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app diff --git a/mod/quiz/tests/behat/app_quiz_navigation.feature b/mod/quiz/tests/behat/app_quiz_navigation.feature index 630ce0feb..c28bc1c86 100644 --- a/mod/quiz/tests/behat/app_quiz_navigation.feature +++ b/mod/quiz/tests/behat/app_quiz_navigation.feature @@ -106,4 +106,4 @@ Feature: Attempt a quiz in app And I should see "Are you sure" And I should see "OK" And I press "OK" in the app - And I should see "Acceptance test site" \ No newline at end of file + And I should see "Acceptance test site" diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index a4b007d0c..a8a324415 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -21,7 +21,7 @@ Feature: Test basic usage of survey activity in app | survey | Test survey name | Test survey | C1 | survey | 0 | @app @3.8.0 - Scenario: Student answers a survey ATTLS and see results + Scenario: Answer a survey & View results (ATTLS) When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app @@ -75,7 +75,7 @@ Feature: Test basic usage of survey activity in app And I should see "1 people have completed this survey so far" @app @3.8.0 - Scenario: Student answers a survey of critical incidents and see results + Scenario: Answer a survey & View results (Critical incidents) Given the following "activities" exist: | activity | name | intro | template |course | idnumber | groupmode | | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | @@ -83,6 +83,11 @@ Feature: Test basic usage of survey activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test survey critical incidents" in the app + And I set the field with xpath "//textarea[@aria-label='At what moment in class were you most engaged as a learner?']" to "1st answer" + And I set the field with xpath "//textarea[@aria-label='At what moment in class were you most distanced as a learner?']" to "2nd answer" + And I set the field with xpath "//textarea[@aria-label='What action from anyone in the forums did you find most affirming or helpful?']" to "3rd answer" + And I set the field with xpath "//textarea[@aria-label='What action from anyone in the forums did you find most puzzling or confusing?']" to "4th answer" + And I set the field with xpath "//textarea[@aria-label='What event surprised you most?']" to "5th answer" And I press "Submit" in the app And I press "OK" in the app Then I should see "Results" @@ -91,9 +96,14 @@ Feature: Test basic usage of survey activity in app And I switch to the browser tab opened by the app And I log in as "student1" Then I should see "Test survey critical incidents" + And I should see "1st answer" + And I should see "2nd answer" + And I should see "3rd answer" + And I should see "4th answer" + And I should see "5th answer" @app @3.8.0 - Scenario: Student answers a survey of Colles (actual) and see results + Scenario: Answer a survey & View results (Colles actual) Given the following "activities" exist: | activity | name | intro | template |course | idnumber | groupmode | | survey | Test survey Colles (actual) | Test survey1 | 1 | C1 | survey1 | 0 | @@ -162,7 +172,7 @@ Feature: Test basic usage of survey activity in app And I should see "1 people have completed this survey so far" @app @3.8.0 - Scenario: Student answers a survey of Colles (preferred) and see results + Scenario: Answer a survey & View results (Colles preferred) Given the following "activities" exist: | activity | name | intro | template | course | idnumber | groupmode | | survey | Test survey Colles (preferred) | Test survey1 | 2 | C1 | survey1 | 0 | @@ -231,7 +241,7 @@ Feature: Test basic usage of survey activity in app And I should see "1 people have completed this survey so far" @app @3.8.0 - Scenario: Student answers a survey of Colles (preferred and actual) and see results + Scenario: Answer a survey & View results (Colles preferred amd actual) Given the following "activities" exist: | activity | name | intro | template | course | idnumber | groupmode | | survey | Test survey Colles (preferred and actual) | Test survey1 | 3 | C1 | survey1 | 0 | @@ -348,7 +358,7 @@ Feature: Test basic usage of survey activity in app And I should see "1 people have completed this survey so far" @app @3.8.0 - Scenario: Student answers a survey offline and sync survey + Scenario: Answer survey offline & Sync survey Given the following "activities" exist: | activity | name | intro | template | course | idnumber | groupmode | | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | @@ -371,7 +381,7 @@ Feature: Test basic usage of survey activity in app But I should not see "This Survey has offline data to be synchronised." @app @3.8.0 - Scenario: Prefetch and auto-sync + Scenario: Prefetch & Auto-sync survey Given the following "activities" exist: | activity | name | intro | template | course | idnumber | groupmode | | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | From bb206a4ffce4f966ddd27cd17cc666dfa19bc20d Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 22 Jun 2020 14:47:26 +0200 Subject: [PATCH 091/220] MOBILE-3401: Remove javascript return evaluation when unnecessary --- tests/behat/behat_local_moodlemobileapp.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/behat/behat_local_moodlemobileapp.php b/tests/behat/behat_local_moodlemobileapp.php index 63e04ee2a..37ff72ea9 100644 --- a/tests/behat/behat_local_moodlemobileapp.php +++ b/tests/behat/behat_local_moodlemobileapp.php @@ -48,7 +48,7 @@ class behat_local_moodlemobileapp extends behat_base { // Force cron tasks execution and wait until they are completed. $operationid = random_string(); - $session->evaluateScript( + $session->executeScript( "cronProvider.forceSyncExecution().then(() => { window['behat_{$operationid}_completed'] = true; });" ); $this->spin( @@ -63,7 +63,7 @@ class behat_local_moodlemobileapp extends behat_base { // Trigger Angular digest cycle multiple times in case some changes have // side-effects that result in further pending operations. for ($ticks = 5; $ticks > 0; $ticks--) { - $session->evaluateScript('appRef.tick();'); + $session->executeScript('appRef.tick();'); } } @@ -77,7 +77,7 @@ class behat_local_moodlemobileapp extends behat_base { $this->spin( function() use ($session) { - $session->evaluateScript('appRef.tick();'); + $session->executeScript('appRef.tick();'); $nodes = $this->find_all('css', 'core-loading ion-spinner'); From 8709c6486d5f81003844060f5131d6161525b8cf Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 1 Jul 2020 11:34:40 +0200 Subject: [PATCH 092/220] MOBILE-3456: Fix forum tests --- mod/forum/tests/behat/app_basic_usage.feature | 82 ++++++++++++------- .../tests/behat/app_basic_usage.feature | 4 +- 2 files changed, 55 insertions(+), 31 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index f3b4fd883..228c13dd2 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -50,7 +50,9 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app And I press "DiscussionSubject" in the app - And I press "Reply" in the app + Then I should see "Reply" + + When I press "Reply" in the app And I set the field "Write your reply" to "ReplyMessage" in the app And I press "Post to forum" in the app Then I should see "DiscussionMessage" @@ -62,11 +64,11 @@ Feature: Test basic usage of forum activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app - And I press "close" in the app + And I press "Add a new discussion topic" in the app And I set the field "Subject" to "starred subject" in the app And I set the field "Message" to "starred message" in the app And I press "Post to forum" in the app - And I press "close" in the app + And I press "Add a new discussion topic" in the app And I set the field "Subject" to "normal subject" in the app And I set the field "Message" to "normal message" in the app And I press "Post to forum" in the app @@ -99,17 +101,17 @@ Feature: Test basic usage of forum activity in app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app - And I press "close" in the app + And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test star" in the app And I set the field "Message" to "Auto-test star message" in the app And I press "Post to forum" in the app - And I press "close" in the app + And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test pin" in the app And I set the field "Message" to "Auto-test pin message" in the app And I press "Post to forum" in the app - And I press "close" in the app - And I set the field "Subject" to "Auto-test" in the app - And I set the field "Message" to "Auto-test message" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "Auto-test plain" in the app + And I set the field "Message" to "Auto-test plain message" in the app And I press "Post to forum" in the app And I press "Display options" near "Auto-test star" in the app And I press "Star this discussion" in the app @@ -117,7 +119,7 @@ Feature: Test basic usage of forum activity in app And I press "Pin this discussion" in the app Then I should see "Auto-test pin" And I should see "Auto-test star" - And I should see "Auto-test" + And I should see "Auto-test plain" When I press "Display options" near "Auto-test pin" in the app And I press "Unpin this discussion" in the app @@ -132,12 +134,14 @@ Feature: Test basic usage of forum activity in app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app - And I press "close" in the app + And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app And I press "Auto-test" in the app - And I press "Information" in the app + Then I should see "Reply" + + When I press "Information" in the app Then I should not see "Star this discussion" And I should not see "Pin this discussion" @@ -147,13 +151,19 @@ Feature: Test basic usage of forum activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app - And I press "close" in the app + And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app + And I should see "Reply" + + When I press the back button in the app And I switch offline mode to "true" - And I press "Reply" in the app + And I press "Auto-test" near "Sort by last post creation date in descending order" in the app + Then I should see "Reply" + + When I press "Reply" in the app And I set the field "Write your reply..." to "not sent reply" in the app And I press "Post to forum" in the app And I press "Display options" near "not sent reply" in the app @@ -178,7 +188,7 @@ Feature: Test basic usage of forum activity in app And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app And I switch offline mode to "true" - And I press "close" in the app + And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -189,7 +199,9 @@ Feature: Test basic usage of forum activity in app When I switch offline mode to "false" And I press "Auto-test" in the app - And I press "Post to forum" in the app + Then I should see "Post to forum" + + When I press "Post to forum" in the app Then I should not see "This Forum has offline data to be synchronised." When I press "Auto-test" near "Sort by last post creation date in descending order" in the app @@ -201,7 +213,7 @@ Feature: Test basic usage of forum activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app - And I press "close" in the app + And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -213,7 +225,9 @@ Feature: Test basic usage of forum activity in app And I press "cloud download" near "Test forum name" in the app And I press "Test forum name" in the app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app - And I press "Display options" near "Reply" in the app + Then I should see "Reply" + + When I press "Display options" near "Reply" in the app Then I should see "Edit" When I press "Edit" in the app @@ -232,7 +246,7 @@ Feature: Test basic usage of forum activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app - And I press "close" in the app + And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -244,7 +258,9 @@ Feature: Test basic usage of forum activity in app And I press "cloud download" near "Test forum name" in the app And I press "Test forum name" in the app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app - And I press "Display options" near "Reply" in the app + Then I should see "Reply" + + When I press "Display options" near "Reply" in the app Then I should see "Delete" When I press "Delete" in the app @@ -268,12 +284,14 @@ Feature: Test basic usage of forum activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app - And I press "close" in the app + And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app And I press "Auto-test" in the app - And I press "Reply" in the app + Then I should see "Reply" + + When I press "Reply" in the app And I set the field "Write your reply..." to "test2" in the app And I press "Post to forum" in the app When I enter the app @@ -281,7 +299,9 @@ Feature: Test basic usage of forum activity in app And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app And I press "Auto-test" in the app - And I press "None" near "Auto-test message" in the app + Then I should see "Reply" + + When I press "None" near "Auto-test message" in the app And I press "1" near "Cancel" in the app And I switch offline mode to "true" And I press "None" near "test2" in the app @@ -329,7 +349,9 @@ Feature: Test basic usage of forum activity in app And I press "Test forum name" in the app And I press "DiscussionSubject" in the app And I switch offline mode to "true" - And I press "Reply" in the app + Then I should see "Reply" + + When I press "Reply" in the app And I set the field "Write your reply" to "ReplyMessage" in the app And I press "Post to forum" in the app Then I should see "DiscussionMessage" @@ -402,10 +424,10 @@ Feature: Test basic usage of forum activity in app And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app - And I set the field "Subject" to "DiscussionSubject" in the app - And I set the field "Message" to "DiscussionMessage" in the app + And I set the field "Subject" to "DiscussionSubject 1" in the app + And I set the field "Message" to "DiscussionMessage 1" in the app And I press "Post to forum" in the app - Then I should see "DiscussionSubject" + Then I should see "DiscussionSubject 1" When I press the back button in the app And I press "Display options" in the app @@ -416,7 +438,7 @@ Feature: Test basic usage of forum activity in app And I set the field "Subject" to "DiscussionSubject 2" in the app And I set the field "Message" to "DiscussionMessage 2" in the app And I press "Post to forum" in the app - Then I should see "DiscussionSubject" + Then I should see "DiscussionSubject 1" And I should see "DiscussionSubject 2" When I press the back button in the app @@ -427,7 +449,7 @@ Feature: Test basic usage of forum activity in app When I press "OK" in the app And I press the back button in the app - And I press "DiscussionSubject" in the app - Then I should see "DiscussionSubject" - And I should see "DiscussionMessage" + And I press "DiscussionSubject 1" in the app + Then I should see "DiscussionSubject 1" + And I should see "DiscussionMessage 1" But I should not see "There was a problem connecting to the site. Please check your connection and try again." diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index b4b0e81ae..2f8de6a52 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -123,7 +123,9 @@ Feature: Test basic usage of glossary in app And I set the field "Message" to "Glossary terms auto-linked: potato car mountain" in the app And I press "Post to forum" in the app And I press "Testing auto-link glossary" near "Last post a few seconds ago" in the app - And I press "car" in the app + Then I should see "car" + + When I press "car" in the app Then the header should be "car" in the app And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." From 1a838bb44182761ba3ea10fd59f1e6a095cc6320 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 16 Jan 2020 17:13:28 +0800 Subject: [PATCH 093/220] MDL-67657 behat: Convert existing uses of executeScript --- behat_app.php | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/behat_app.php b/behat_app.php index af82844ec..e474ffc67 100644 --- a/behat_app.php +++ b/behat_app.php @@ -297,8 +297,7 @@ class behat_app extends behat_base { }, false, 60); // Run the scripts to install Moodle 'pending' checks. - $this->getSession()->executeScript( - file_get_contents(__DIR__ . '/app_behat_runtime.js')); + $this->execute_script(file_get_contents(__DIR__ . '/app_behat_runtime.js')); // Wait until the site login field appears OR the main page. $situation = $this->spin( @@ -373,8 +372,7 @@ class behat_app extends behat_base { */ public function i_press_the_standard_button_in_the_app(string $button) { $this->spin(function($context, $args) use ($button) { - $result = $this->getSession()->evaluateScript('return window.behat.pressStandard("' . - $button . '");'); + $result = $this->evaluate_script("return window.behat.pressStandard('{$button}');"); if ($result !== 'OK') { throw new DriverException('Error pressing standard button - ' . $result); } @@ -391,7 +389,7 @@ class behat_app extends behat_base { */ public function i_close_the_popup_in_the_app() { $this->spin(function($context, $args) { - $result = $this->getSession()->evaluateScript('return window.behat.closePopup();'); + $result = $this->evaluate_script("return window.behat.closePopup();"); if ($result !== 'OK') { throw new DriverException('Error closing popup - ' . $result); } @@ -449,7 +447,7 @@ class behat_app extends behat_base { } else { $nearbit = ''; } - $result = $context->getSession()->evaluateScript('return window.behat.press("' . + $result = $this->evaluate_script('return window.behat.press("' . addslashes_js($text) . '"' . $nearbit .');'); if ($result !== 'OK') { throw new DriverException('Error pressing item - ' . $result); @@ -472,7 +470,7 @@ class behat_app extends behat_base { */ public function i_set_the_field_in_the_app(string $field, string $value) { $this->spin(function($context, $args) use ($field, $value) { - $result = $this->getSession()->evaluateScript('return window.behat.setField("' . + $result = $this->evaluate_script('return window.behat.setField("' . addslashes_js($field) . '", "' . addslashes_js($value) . '");'); if ($result !== 'OK') { throw new DriverException('Error setting field - ' . $result); @@ -494,7 +492,7 @@ class behat_app extends behat_base { */ public function the_header_should_be_in_the_app(string $text) { $result = $this->spin(function($context, $args) { - $result = $this->getSession()->evaluateScript('return window.behat.getHeader();'); + $result = $this->evaluate_script('return window.behat.getHeader();'); if (substr($result, 0, 3) !== 'OK:') { throw new DriverException('Error getting header - ' . $result); } @@ -536,7 +534,7 @@ class behat_app extends behat_base { if (count($names) !== 2) { throw new DriverException('Expected to see 2 tabs open, not ' . count($names)); } - $this->getSession()->getDriver()->executeScript('window.close()'); + $this->execute_script('window.close()'); $this->getSession()->switchToWindow($names[0]); } @@ -548,6 +546,6 @@ class behat_app extends behat_base { * @throws DriverException If the navigator.online mode is not available */ public function i_switch_offline_mode(string $offline) { - $this->getSession()->evaluateScript('appProvider.setForceOffline(' . $offline . ');'); + $this->execute_script('appProvider.setForceOffline(' . $offline . ');'); } } From fd42bc3ef9f24f2a39e41e92af2755202072e46f Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 25 Jun 2020 14:39:38 +0800 Subject: [PATCH 094/220] MDL-69138 behat: Update session->visit() to use visit step --- behat_app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/behat_app.php b/behat_app.php index e474ffc67..ce9f392c0 100644 --- a/behat_app.php +++ b/behat_app.php @@ -283,7 +283,7 @@ class behat_app extends behat_base { global $CFG; // Visit the Ionic URL and wait for it to load. - $this->getSession()->visit($url); + $this->execute('behat_general::i_visit', [$url]); $this->spin( function($context, $args) { $title = $context->getSession()->getPage()->find('xpath', '//title'); From c06cd808795977b530993830773fdf6fa16ff08e Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 6 Aug 2020 12:08:43 +0200 Subject: [PATCH 095/220] MDL-69421 behat: Revert app behat navigation to call session visit --- behat_app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/behat_app.php b/behat_app.php index ce9f392c0..e474ffc67 100644 --- a/behat_app.php +++ b/behat_app.php @@ -283,7 +283,7 @@ class behat_app extends behat_base { global $CFG; // Visit the Ionic URL and wait for it to load. - $this->execute('behat_general::i_visit', [$url]); + $this->getSession()->visit($url); $this->spin( function($context, $args) { $title = $context->getSession()->getPage()->find('xpath', '//title'); From 0deeb5584c873be223bbb6226987662cb7282e0c Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 24 Aug 2020 12:48:31 +0200 Subject: [PATCH 096/220] MDL-69421: Fix tests running with moodle-ci-runner --- mod/choice/tests/behat/app_basic_usage.feature | 1 + mod/login/tests/behat/app_basic_usage.feature | 2 +- tests/behat/behat_local_moodlemobileapp.php | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 74cfd7429..86055ca25 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -130,6 +130,7 @@ Feature: Test basic usage of choice activity in app And I should not see "Option 3: 0" When I run cron tasks in the app + And I wait loading to finish in the app Then I should see "Option 1: 0" And I should see "Option 2: 1" And I should see "Option 3: 0" diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index 4321f9ca9..0071ad1a7 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -21,7 +21,7 @@ Feature: Test basic usage of login in app Scenario: Add a new site in the app & Site name in displayed when adding a new site When I enter the app And I press the back button in the app - And I set the field "https://campus.example.edu" to "webserver" in the app + And I set the field "https://campus.example.edu" to "$WEBSERVER" in the app And I press "Connect to your site" in the app Then I should see "Acceptance test site" diff --git a/tests/behat/behat_local_moodlemobileapp.php b/tests/behat/behat_local_moodlemobileapp.php index 37ff72ea9..603f055bf 100644 --- a/tests/behat/behat_local_moodlemobileapp.php +++ b/tests/behat/behat_local_moodlemobileapp.php @@ -97,4 +97,21 @@ class behat_local_moodlemobileapp extends behat_base { ); } + /** + * Replaces $WEBSERVER for webserver env variable value, defaults to "webserver" if it is not set. + * + * @Transform /^(.*\$WEBSERVER.*)$/ + * @param string $text Text. + * @return string + */ + public function arg_replace_webserver_env($text) { + $webserver = getenv('WEBSERVER'); + + if ($webserver === false) { + $webserver = 'webserver'; + } + + return str_replace('$WEBSERVER', $webserver, $text); + } + } From 20b0afcade2abce24d6fe091d19e3b83dd981bc8 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 3 Sep 2020 11:42:45 +0200 Subject: [PATCH 097/220] MOBILE-3523: Use $WWWROOT to get moodle site url in tests --- mod/login/tests/behat/app_basic_usage.feature | 2 +- tests/behat/behat_local_moodlemobileapp.php | 14 +++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index 0071ad1a7..0aa02605f 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -21,7 +21,7 @@ Feature: Test basic usage of login in app Scenario: Add a new site in the app & Site name in displayed when adding a new site When I enter the app And I press the back button in the app - And I set the field "https://campus.example.edu" to "$WEBSERVER" in the app + And I set the field "https://campus.example.edu" to "$WWWROOT" in the app And I press "Connect to your site" in the app Then I should see "Acceptance test site" diff --git a/tests/behat/behat_local_moodlemobileapp.php b/tests/behat/behat_local_moodlemobileapp.php index 603f055bf..1629e0e41 100644 --- a/tests/behat/behat_local_moodlemobileapp.php +++ b/tests/behat/behat_local_moodlemobileapp.php @@ -98,20 +98,16 @@ class behat_local_moodlemobileapp extends behat_base { } /** - * Replaces $WEBSERVER for webserver env variable value, defaults to "webserver" if it is not set. + * Replaces $WWWROOT for the url of the Moodle site. * - * @Transform /^(.*\$WEBSERVER.*)$/ + * @Transform /^(.*\$WWWROOT.*)$/ * @param string $text Text. * @return string */ - public function arg_replace_webserver_env($text) { - $webserver = getenv('WEBSERVER'); + public function arg_replace_wwwroot($text) { + global $CFG; - if ($webserver === false) { - $webserver = 'webserver'; - } - - return str_replace('$WEBSERVER', $webserver, $text); + return str_replace('$WWWROOT', $CFG->behat_wwwroot, $text); } } From 3ad458f9727eb09f43aef2638531a407047803f6 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 23 Sep 2020 18:06:18 +0200 Subject: [PATCH 098/220] MOBILE-3523: Fix forum tests --- mod/forum/tests/behat/app_basic_usage.feature | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 228c13dd2..02a47e171 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -231,15 +231,11 @@ Feature: Test basic usage of forum activity in app Then I should see "Edit" When I press "Edit" in the app + And I switch offline mode to "true" And I set the field "Write your reply..." to "Auto-test message edited" in the app And I press "Save changes" in the app - And I switch offline mode to "true" - And I press "Display options" near "Reply" in the app Then I should see "There was a problem connecting to the site. Please check your connection and try again." - When I press "OK" in the app - And I should not see "Edit" - @app @3.8.0 Scenario: Delete a forum post (only online) When I enter the app @@ -267,6 +263,7 @@ Feature: Test basic usage of forum activity in app And I press "Cancel" in the app And I switch offline mode to "true" And I press "Display options" near "Reply" in the app + And I press "Delete" in the app Then I should see "There was a problem connecting to the site. Please check your connection and try again." When I press "OK" in the app From 588f38e624c522af61f739cb2c87819f6c37ab36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Fri, 25 Sep 2020 12:23:04 +0200 Subject: [PATCH 099/220] MOBILE-3519 forum: Test changes --- mod/forum/tests/behat/app_basic_usage.feature | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 02a47e171..175c4bb52 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -263,10 +263,6 @@ Feature: Test basic usage of forum activity in app And I press "Cancel" in the app And I switch offline mode to "true" And I press "Display options" near "Reply" in the app - And I press "Delete" in the app - Then I should see "There was a problem connecting to the site. Please check your connection and try again." - - When I press "OK" in the app Then I should not see "Delete" When I switch offline mode to "false" From 7ce1e2b2f9cbbcae5db6d03eca095ca87fbcbb03 Mon Sep 17 00:00:00 2001 From: Thinh Pham Date: Tue, 2 Mar 2021 13:34:53 +0700 Subject: [PATCH 100/220] MDL-70727 Behat: function scrollIntoView not working in the app --- app_behat_runtime.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/app_behat_runtime.js b/app_behat_runtime.js index 56fdbc3b3..182e5c185 100644 --- a/app_behat_runtime.js +++ b/app_behat_runtime.js @@ -476,6 +476,23 @@ return 'OK'; }; + /** + * Get main navigation controller. + * + * @return {Object} main navigation controller. + */ + var getNavCtrl = function() { + var mainNav = window.appProvider.appCtrl.getRootNavs()[0].getActiveChildNav(); + if (mainNav && mainNav.tabsIds.length && mainNav.firstSelectedTab) { + var tabPos = mainNav.tabsIds.indexOf(mainNav.firstSelectedTab); + if (tabPos !== -1 && mainNav._tabs && mainNav._tabs.length > tabPos) { + return mainNav._tabs[tabPos]; + } + } + // Fallback to return main nav - this will work but will overlay current tab. + return window.appProvider.appCtrl.getRootNavs()[0]; + }; + /** * Function to press arbitrary item based on its text or Aria label. * @@ -493,9 +510,13 @@ return 'ERROR: ' + error.message; } - // Simulate a mouse click on the button. - found.scrollIntoView(); + var mainContent = getNavCtrl().getActive()._cntDir; var rect = found.getBoundingClientRect(); + + // Scroll the item into view. + mainContent.scrollTo(rect.x, rect.y); + + // Simulate a mouse click on the button. var eventOptions = {clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2, bubbles: true, view: window, cancelable: true}; setTimeout(function() { From 7d1fd94c19b73db722c2eebdb4f4ef668b4de884 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 25 Mar 2021 13:50:27 +0100 Subject: [PATCH 101/220] MDL-71194 behat: Fix app tests --- app_behat_runtime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app_behat_runtime.js b/app_behat_runtime.js index 182e5c185..8bd63730d 100644 --- a/app_behat_runtime.js +++ b/app_behat_runtime.js @@ -510,7 +510,7 @@ return 'ERROR: ' + error.message; } - var mainContent = getNavCtrl().getActive()._cntDir; + var mainContent = getNavCtrl().getActive().contentRef().nativeElement; var rect = found.getBoundingClientRect(); // Scroll the item into view. From 15e79257627c897f55cc3cf8893a3e8d8c8ae81a Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 22 Apr 2021 09:32:32 +0200 Subject: [PATCH 102/220] MDL-68969 behat: Move app behat files to plugin folder --- app_behat_runtime.js => tests/behat/app_behat_runtime.js | 0 behat_app.php => tests/behat/behat_app.php | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename app_behat_runtime.js => tests/behat/app_behat_runtime.js (100%) rename behat_app.php => tests/behat/behat_app.php (100%) diff --git a/app_behat_runtime.js b/tests/behat/app_behat_runtime.js similarity index 100% rename from app_behat_runtime.js rename to tests/behat/app_behat_runtime.js diff --git a/behat_app.php b/tests/behat/behat_app.php similarity index 100% rename from behat_app.php rename to tests/behat/behat_app.php From 17006dcc4e742e98bfaf6bb907cc70f93696ee98 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 27 Apr 2021 17:43:47 +0200 Subject: [PATCH 103/220] MOBILE-3738 behat: Prepare 3.9.5 tests --- .../tests/behat/app_basic_usage.feature | 2 +- mod/chat/tests/behat/app_basic_usage.feature | 2 +- .../tests/behat/app_basic_usage.feature | 2 +- .../tests/behat/app_basic_usage.feature | 2 +- .../tests/behat/app_basic_usage.feature | 2 +- .../tests/behat/app_course_completion.feature | 2 +- mod/course/tests/behat/app_courselist.feature | 80 ++-- .../tests/behat/app_basic_usage.feature | 2 +- mod/data/tests/behat/app_data_entries.feature | 2 +- mod/data/tests/behat/app_data_sync.feature | 2 +- mod/forum/tests/behat/app_basic_usage.feature | 2 +- .../tests/behat/app_basic_usage.feature | 2 +- mod/login/tests/behat/app_basic_usage.feature | 2 +- .../tests/behat/app_basic_usage.feature | 2 +- mod/quiz/tests/behat/app_basic_usage.feature | 2 +- .../tests/behat/app_quiz_navigation.feature | 2 +- .../tests/behat/app_basic_usage.feature | 2 +- tests/behat/app_behat_runtime.js | 349 ++++++++---------- tests/behat/behat_app.php | 74 +++- 19 files changed, 285 insertions(+), 250 deletions(-) diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index 1bfb70b57..778cfe1ec 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_assign @app @javascript +@mod @mod_assign @app @app_upto3.9.4 @javascript Feature: Test basic usage of assignment activity in app In order to participate in the assignment while using the mobile app I need basic assignment functionality to work diff --git a/mod/chat/tests/behat/app_basic_usage.feature b/mod/chat/tests/behat/app_basic_usage.feature index 424c80051..5838fa4ae 100755 --- a/mod/chat/tests/behat/app_basic_usage.feature +++ b/mod/chat/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_chat @app @javascript +@mod @mod_chat @app @app_upto3.9.4 @javascript Feature: Test basic usage of chat in app As a student I need basic chat functionality to work diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 86055ca25..22ea6aa69 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_choice @app @javascript +@mod @mod_choice @app @app_upto3.9.4 @javascript Feature: Test basic usage of choice activity in app In order to participate in the choice while using the mobile app As a student diff --git a/mod/comments/tests/behat/app_basic_usage.feature b/mod/comments/tests/behat/app_basic_usage.feature index e4066d82d..2bc874f98 100755 --- a/mod/comments/tests/behat/app_basic_usage.feature +++ b/mod/comments/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_comments @app @javascript +@mod @mod_comments @app @app_upto3.9.4 @javascript Feature: Test basic usage of comments in app In order to participate in the comments while using the mobile app As a student diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 0e66729d6..a74a97831 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_course @app @javascript +@mod @mod_course @app @app_upto3.9.4 @javascript Feature: Test basic usage of one course in app In order to participate in one course while using the mobile app As a student diff --git a/mod/course/tests/behat/app_course_completion.feature b/mod/course/tests/behat/app_course_completion.feature index a3c2475a5..34d482722 100644 --- a/mod/course/tests/behat/app_course_completion.feature +++ b/mod/course/tests/behat/app_course_completion.feature @@ -1,4 +1,4 @@ -@core @core_course @app @javascript +@core @core_course @app @app_upto3.9.4 @javascript Feature: Check course completion feature. In order to track the progress of the course on mobile device As a student diff --git a/mod/course/tests/behat/app_courselist.feature b/mod/course/tests/behat/app_courselist.feature index 1e1bc1e1f..7a508f9f3 100644 --- a/mod/course/tests/behat/app_courselist.feature +++ b/mod/course/tests/behat/app_courselist.feature @@ -22,17 +22,17 @@ Feature: Test course list shown on app start tab Scenario: View courses (shortnames not displayed) When I enter the app And I log in as "student1" - Then I should see "Course 1" - But I should not see "Course 2" - But I should not see "C1" - But I should not see "C2" + Then I should find "Course 1" in the app + But I should not find "Course 2" in the app + But I should not find "C1" in the app + But I should not find "C2" in the app When I enter the app And I log in as "student2" - Then I should see "Course 1" - And I should see "Course 2" - But I should not see "C1" - But I should not see "C2" + Then I should find "Course 1" in the app + And I should find "Course 2" in the app + But I should not find "C1" in the app + But I should not find "C2" in the app Scenario: Filter courses Given the following config values are set as admin: @@ -78,26 +78,46 @@ Feature: Test course list shown on app start tab | student2 | Z10 | student | When I enter the app And I log in as "student2" - Then I press "Display options" near "Course overview" in the app - Then I should see "C1" - And I should see "C2" - And I should see "C3" - And I should see "C4" - And I should see "C5" - And I should see "C6" - Then I press "Filter my courses" in the app - And I set the field "Filter my courses" to "fr" in the app - Then I should not see "C1" - And I should not see "C2" - And I should see "C3" - And I should see "C4" - And I should not see "C5" - And I should not see "C6" - And I press "Display options" near "Course overview" in the app + Then I should find "C1" in the app + And I should find "C2" in the app + And I should find "C3" in the app + And I should find "C4" in the app + And I should find "C5" in the app + And I should find "C6" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Frog 3" in the app + And I should find "Frog 4" in the app + And I should find "Course 5" in the app + And I should find "Toad 6" in the app + + When I press "Display options" near "Course overview" in the app And I press "Filter my courses" in the app - Then I should see "C1" - And I should see "C2" - And I should see "C3" - And I should see "C4" - And I should see "C5" - And I should see "C6" + And I set the field "Filter my courses" to "fr" in the app + Then I should find "C3" in the app + And I should find "C4" in the app + And I should find "Frog 3" in the app + And I should find "Frog 4" in the app + But I should not find "C1" in the app + And I should not find "C2" in the app + And I should not find "C5" in the app + And I should not find "C6" in the app + And I should not find "Course 1" in the app + And I should not find "Course 2" in the app + And I should not find "Course 5" in the app + And I should not find "Toad 6" in the app + + When I press "Display options" near "Course overview" in the app + And I press "Filter my courses" in the app + Then I should find "C1" in the app + And I should find "C2" in the app + And I should find "C3" in the app + And I should find "C4" in the app + And I should find "C5" in the app + And I should find "C6" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Frog 3" in the app + And I should find "Frog 4" in the app + And I should find "Course 5" in the app + And I should find "Toad 6" in the app diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index fea9ce84a..e81882cde 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_courses @app @javascript +@mod @mod_courses @app @app_upto3.9.4 @javascript Feature: Test basic usage of courses in app In order to participate in the courses while using the mobile app As a student diff --git a/mod/data/tests/behat/app_data_entries.feature b/mod/data/tests/behat/app_data_entries.feature index 41e8ad6c5..5fb346918 100644 --- a/mod/data/tests/behat/app_data_entries.feature +++ b/mod/data/tests/behat/app_data_entries.feature @@ -1,4 +1,4 @@ -@mod @mod_data @app @javascript +@mod @mod_data @app @app_upto3.9.4 @javascript Feature: Users can manage entries in database activities In order to populate databases As a user diff --git a/mod/data/tests/behat/app_data_sync.feature b/mod/data/tests/behat/app_data_sync.feature index f0b147b95..065ffe35f 100644 --- a/mod/data/tests/behat/app_data_sync.feature +++ b/mod/data/tests/behat/app_data_sync.feature @@ -1,4 +1,4 @@ -@mod @mod_data @app @javascript +@mod @mod_data @app @app_upto3.9.4 @javascript Feature: Users can store entries in database activities when offline and sync when online In order to populate databases while offline As a user diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 175c4bb52..473cbfc21 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_forum @app @javascript +@mod @mod_forum @app @app_upto3.9.4 @javascript Feature: Test basic usage of forum activity in app In order to participate in the forum while using the mobile app As a student diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index 2f8de6a52..db323a308 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_glossary @app @javascript +@mod @mod_glossary @app @app_upto3.9.4 @javascript Feature: Test basic usage of glossary in app In order to participate in the glossaries while using the mobile app As a student diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index 0aa02605f..fc0f78236 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_login @app @javascript +@mod @mod_login @app @app_upto3.9.4 @javascript Feature: Test basic usage of login in app I need basic login functionality to work diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index f33f06c13..a2aa8fa3f 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_messages @app @javascript +@mod @mod_messages @app @app_upto3.9.4 @javascript Feature: Test basic usage of messages in app In order to participate with messages while using the mobile app As a student diff --git a/mod/quiz/tests/behat/app_basic_usage.feature b/mod/quiz/tests/behat/app_basic_usage.feature index ca652fdcb..7b2f92086 100755 --- a/mod/quiz/tests/behat/app_basic_usage.feature +++ b/mod/quiz/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_quiz @app @javascript +@mod @mod_quiz @app @app_upto3.9.4 @javascript Feature: Attempt a quiz in app As a student In order to demonstrate what I know diff --git a/mod/quiz/tests/behat/app_quiz_navigation.feature b/mod/quiz/tests/behat/app_quiz_navigation.feature index c28bc1c86..75b8b7a9d 100644 --- a/mod/quiz/tests/behat/app_quiz_navigation.feature +++ b/mod/quiz/tests/behat/app_quiz_navigation.feature @@ -1,4 +1,4 @@ -@mod @mod_quiz @app @javascript +@mod @mod_quiz @app @app_upto3.9.4 @javascript Feature: Attempt a quiz in app As a student In order to demonstrate what I know diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index a8a324415..fcba1840e 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_survey @app @javascript +@mod @mod_survey @app @app_upto3.9.4 @javascript Feature: Test basic usage of survey activity in app In order to participate in surveys while using the mobile app As a student diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 8bd63730d..c725827f5 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -174,6 +174,26 @@ var observer = new MutationObserver(mutationCallback); observer.observe(document, {attributes: true, childList: true, subtree: true}); + /** + * Check if an element is visible. + * + * @param {HTMLElement} element Element + * @param {HTMLElement} container Container + * @returns {boolean} Whether the element is visible or not + */ + var isElementVisible = (element, container) => { + if (element.getAttribute('aria-hidden') === 'true' || getComputedStyle(element).display === 'none') + return false; + + if (element.parentElement === container) + return true; + + if (!element.parentElement) + return false; + + return isElementVisible(element.parentElement, container); + }; + /** * Generic shared function to find possible xpath matches within the document, that are visible, * and then process them using a callback function. @@ -199,194 +219,107 @@ } }; + /** + * Finds an element within a given container. + * + * @param {HTMLElement} container Parent element to search the element within + * @param {string} text Text to look for + * @return {HTMLElement} Found element + */ + var findElementBasedOnTextWithin = (container, text) => { + const attributesSelector = `[aria-label*="${text}"], a[title*="${text}"], img[alt*="${text}"]`; + + for (const foundByAttributes of container.querySelectorAll(attributesSelector)) { + if (isElementVisible(foundByAttributes, container)) + return foundByAttributes; + } + + const treeWalker = document.createTreeWalker( + container, + NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_DOCUMENT_FRAGMENT | NodeFilter.SHOW_TEXT, + { + acceptNode: node => { + if ( + node instanceof HTMLStyleElement || + node instanceof HTMLLinkElement || + node instanceof HTMLScriptElement + ) + return NodeFilter.FILTER_REJECT; + + if ( + node instanceof HTMLElement && ( + node.getAttribute('aria-hidden') === 'true' || getComputedStyle(node).display === 'none' + ) + ) + return NodeFilter.FILTER_REJECT; + + return NodeFilter.FILTER_ACCEPT; + } + }, + ); + + let currentNode; + while (currentNode = treeWalker.nextNode()) { + if (currentNode instanceof Text) { + if (currentNode.textContent.includes(text)) { + return currentNode.parentElement; + } + + continue; + } + + const labelledBy = currentNode.getAttribute('aria-labelledby'); + if (labelledBy && container.querySelector(`#${labelledBy}`)?.innerText?.includes(text)) + return currentNode; + + if (currentNode.shadowRoot) { + for (const childNode of currentNode.shadowRoot.childNodes) { + if (!childNode) { + continue; + } + + if (childNode.matches(attributesSelector)) { + return childNode; + } + + const foundByText = findElementBasedOnTextWithin(childNode, text); + + if (foundByText) { + return foundByText; + } + } + } + } + }; + /** * Function to find an element based on its text or Aria label. * * @param {string} text Text (full or partial) * @param {string} [near] Optional 'near' text - if specified, must have a single match on page * @return {HTMLElement} Found element - * @throws {string} Error message beginning 'ERROR:' if something went wrong */ var findElementBasedOnText = function(text, near) { - // Find all the elements that contain this text (and don't have a child element that - // contains it - i.e. the most specific elements). - var escapedText = text.replace('"', '""'); - var exactMatches = []; - var anyMatches = []; - findPossibleMatches('//*[contains(normalize-space(.), "' + escapedText + - '") and not(child::*[contains(normalize-space(.), "' + escapedText + '")])]', - function(match) { - // Get the text. Note that innerText returns capitalised values for Android buttons - // for some reason, so we'll have to do a case-insensitive match. - var matchText = match.innerText.trim().toLowerCase(); + const topContainer = document.querySelector('ion-alert, ion-popover, ion-action-sheet, core-ion-tab.show-tab ion-page.show-page, ion-page.show-page, html'); + let container = topContainer; - // Let's just check - is this actually a label for something else? If so we will click - // that other thing instead. - var labelId = document.evaluate('string(ancestor-or-self::ion-label[@id][1]/@id)', match).stringValue; - if (labelId) { - var target = document.querySelector('*[aria-labelledby=' + labelId + ']'); - if (target) { - match = target; - } - } + if (topContainer && near) { + const nearElement = findElementBasedOnText(near); - // Add to array depending on if it's an exact or partial match. - if (matchText === text.toLowerCase()) { - exactMatches.push(match); - } else { - anyMatches.push(match); - } - }); - - // Find all the Aria labels that contain this text. - var exactLabelMatches = []; - var anyLabelMatches = []; - findPossibleMatches('//*[@aria-label and contains(@aria-label, "' + escapedText + '")]' + - '| //a[@title and contains(@title, "' + escapedText + '")]' + - '| //img[@alt and contains(@alt, "' + escapedText + '")]', function(match) { - // Add to array depending on if it's an exact or partial match. - var attributeData = match.getAttribute('aria-label') || - match.getAttribute('title') || - match.getAttribute('alt'); - if (attributeData.trim() === text) { - exactLabelMatches.push(match); - } else { - anyLabelMatches.push(match); - } - }); - - // If the 'near' text is set, use it to filter results. - var nearAncestors = []; - if (near !== undefined) { - escapedText = near.replace('"', '""'); - var exactNearMatches = []; - var anyNearMatches = []; - findPossibleMatches('//*[contains(normalize-space(.), "' + escapedText + - '") and not(child::*[contains(normalize-space(.), "' + escapedText + - '")])]', function(match) { - // Get the text. - var matchText = match.innerText.trim(); - - // Add to array depending on if it's an exact or partial match. - if (matchText === text) { - exactNearMatches.push(match); - } else { - anyNearMatches.push(match); - } - }); - - var nearFound = null; - - // If there is an exact text match, use that (regardless of other matches). - if (exactNearMatches.length > 1) { - throw new Error('Too many exact matches for near text'); - } else if (exactNearMatches.length) { - nearFound = exactNearMatches[0]; + if (!nearElement) { + return; } - if (nearFound === null) { - // If there is one partial text match, use that. - if (anyNearMatches.length > 1) { - throw new Error('Too many partial matches for near text'); - } else if (anyNearMatches.length) { - nearFound = anyNearMatches[0]; - } - } - - if (!nearFound) { - throw new Error('No matches for near text'); - } - - while (nearFound) { - nearAncestors.push(nearFound); - nearFound = nearFound.parentNode; - } - - /** - * Checks the number of steps up the tree from a specified node before getting to an - * ancestor of the 'near' item - * - * @param {HTMLElement} node HTML node - * @returns {number} Number of steps up, or Number.MAX_SAFE_INTEGER if it never matched - */ - var calculateNearDepth = function(node) { - var depth = 0; - while (node) { - var ancestorDepth = nearAncestors.indexOf(node); - if (ancestorDepth !== -1) { - return depth + ancestorDepth; - } - node = node.parentNode; - depth++; - } - return Number.MAX_SAFE_INTEGER; - }; - - /** - * Reduces an array to include only the nearest in each category. - * - * @param {Array} arr Array to - * @return {Array} Array including only the items with minimum 'near' depth - */ - var filterNonNearest = function(arr) { - var nearDepth = arr.map(function(node) { - return calculateNearDepth(node); - }); - var minDepth = Math.min.apply(null, nearDepth); - return arr.filter(function(element, index) { - return nearDepth[index] == minDepth; - }); - }; - - // Filter all the category arrays. - exactMatches = filterNonNearest(exactMatches); - exactLabelMatches = filterNonNearest(exactLabelMatches); - anyMatches = filterNonNearest(anyMatches); - anyLabelMatches = filterNonNearest(anyLabelMatches); + container = nearElement.parentElement; } - // Select the resulting match. Note this 'do' loop is not really a loop, it is just so we - // can easily break out of it as soon as we find a match. - var found = null; do { - // If there is an exact text match, use that (regardless of other matches). - if (exactMatches.length > 1) { - throw new Error('Too many exact matches for text'); - } else if (exactMatches.length) { - found = exactMatches[0]; - break; + const node = findElementBasedOnTextWithin(container, text); + + if (node) { + return node; } - - // If there is an exact label match, use that. - if (exactLabelMatches.length > 1) { - throw new Error('Too many exact label matches for text'); - } else if (exactLabelMatches.length) { - found = exactLabelMatches[0]; - break; - } - - // If there is one partial text match, use that. - if (anyMatches.length > 1) { - throw new Error('Too many partial matches for text'); - } else if (anyMatches.length) { - found = anyMatches[0]; - break; - } - - // Finally if there is one partial label match, use that. - if (anyLabelMatches.length > 1) { - throw new Error('Too many partial label matches for text'); - } else if (anyLabelMatches.length) { - found = anyLabelMatches[0]; - break; - } - } while (false); - - if (!found) { - throw new Error('No matches for text'); - } - - return found; + } while ((container = container.parentElement) && container !== topContainer); }; /** @@ -476,6 +409,29 @@ return 'OK'; }; + /** + * Function to find an arbitrary item based on its text or aria label. + * + * @param {string} text Text (full or partial) + * @param {string} [near] Optional 'near' text + * @return {string} OK if successful, or ERROR: followed by message + */ + var behatFind = function(text, near) { + log(`Action - Find ${text}`); + + try { + const element = findElementBasedOnText(text, near); + + if (!element) { + return 'ERROR: No matches for text'; + } + + return 'OK'; + } catch (error) { + return 'ERROR: ' + error.message; + } + }; + /** * Get main navigation controller. * @@ -497,7 +453,7 @@ * Function to press arbitrary item based on its text or Aria label. * * @param {string} text Text (full or partial) - * @param {string} near Optional 'near' text - if specified, must have a single match on page + * @param {string} near Optional 'near' text * @return {string} OK if successful, or ERROR: followed by message */ var behatPress = function(text, near) { @@ -506,28 +462,37 @@ var found; try { found = findElementBasedOnText(text, near); + + if (!found) { + return 'ERROR: No matches for text'; + } } catch (error) { return 'ERROR: ' + error.message; } - var mainContent = getNavCtrl().getActive().contentRef().nativeElement; - var rect = found.getBoundingClientRect(); + if (window.BehatMoodleAppLegacy) { + var mainContent = getNavCtrl().getActive().contentRef().nativeElement; + var rect = found.getBoundingClientRect(); - // Scroll the item into view. - mainContent.scrollTo(rect.x, rect.y); + // Scroll the item into view. + mainContent.scrollTo(rect.x, rect.y); - // Simulate a mouse click on the button. - var eventOptions = {clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2, - bubbles: true, view: window, cancelable: true}; - setTimeout(function() { - found.dispatchEvent(new MouseEvent('mousedown', eventOptions)); - }, 0); - setTimeout(function() { - found.dispatchEvent(new MouseEvent('mouseup', eventOptions)); - }, 0); - setTimeout(function() { - found.dispatchEvent(new MouseEvent('click', eventOptions)); - }, 0); + // Simulate a mouse click on the button. + var eventOptions = {clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2, + bubbles: true, view: window, cancelable: true}; + setTimeout(function() { + found.dispatchEvent(new MouseEvent('mousedown', eventOptions)); + }, 0); + setTimeout(function() { + found.dispatchEvent(new MouseEvent('mouseup', eventOptions)); + }, 0); + setTimeout(function() { + found.dispatchEvent(new MouseEvent('click', eventOptions)); + }, 0); + } else { + found.scrollIntoView(); + setTimeout(() => found.click(), 300); + } // Mark busy until the button click finishes processing. addPendingDelay(); @@ -547,7 +512,10 @@ var resultCount = 0; var titles = Array.from(document.querySelectorAll('ion-header ion-title')); titles.forEach(function(title) { - if (title.offsetParent) { + if ( + (window.BehatMoodleAppLegacy && title.offsetParent) || + (!window.BehatMoodleAppLegacy && isElementVisible(title, document.body)) + ) { result = title.innerText.trim(); resultCount++; } @@ -670,6 +638,7 @@ window.behat = { pressStandard : behatPressStandard, closePopup : behatClosePopup, + find : behatFind, press : behatPress, setField : behatSetField, getHeader : behatGetHeader, diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index e474ffc67..c1c14c80b 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -25,7 +25,7 @@ // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. -require_once(__DIR__ . '/../../behat/behat_base.php'); +require_once(__DIR__ . '/../../../../lib/behat/behat_base.php'); use Behat\Mink\Exception\DriverException; use Behat\Mink\Exception\ExpectationException; @@ -63,7 +63,7 @@ class behat_app extends behat_base { $this->check_behat_setup(); $this->fix_moodle_setup(); $this->ionicurl = $this->start_or_reuse_ionic(); -} + } /** * Opens the Moodle app in the browser. @@ -93,6 +93,33 @@ class behat_app extends behat_base { $this->prepare_browser($this->ionicurl); } + /** + * Finds elements in the app. + * + * @Then /^I should(?P not)? find "(?P(?:[^"]|\\")*)"(?: near "(?P(?:[^"]|\\")*)")? in the app$/ + * @param string $text + */ + public function i_find_in_the_app($not, $text='', $near='') { + $not = !empty($not); + $text = addslashes_js($text); + $near = addslashes_js($near); + + $this->spin(function() use ($not, $text, $near) { + $result = $this->evaluate_script("return window.behat.find(\"$text\", \"$near\");"); + + if ($not && $result === 'OK') { + throw new DriverException('Error, found an item that should not be found'); + } + + if (!$not && $result !== 'OK') { + throw new DriverException('Error finding item - ' . $result); + } + + return true; + }); + $this->wait_for_pending_js(); + } + /** * Checks the Behat setup - tags and configuration. * @@ -282,14 +309,23 @@ class behat_app extends behat_base { protected function prepare_browser(string $url) { global $CFG; + // Check whether the app is running a legacy version. + $json = @file_get_contents("$url/assets/env.json") ?: @file_get_contents("$url/config.json"); + $data = json_decode($json); + $appversion = $data->build->version ?? str_replace('-dev', '', $data->versionname); + $islegacy = version_compare($appversion, '3.9.5', '<'); + // Visit the Ionic URL and wait for it to load. $this->getSession()->visit($url); $this->spin( - function($context, $args) { + function($context) use ($islegacy) { $title = $context->getSession()->getPage()->find('xpath', '//title'); if ($title) { $text = $title->getHtml(); - if ($text === 'Moodle Desktop') { + if ( + ($islegacy && $text === 'Moodle Desktop') || + (!$islegacy && $text === 'Moodle App') + ) { return true; } } @@ -297,20 +333,25 @@ class behat_app extends behat_base { }, false, 60); // Run the scripts to install Moodle 'pending' checks. + $islegacyboolean = $islegacy ? 'true' : 'false'; + $this->execute_script("window.BehatMoodleAppLegacy = $islegacyboolean;"); $this->execute_script(file_get_contents(__DIR__ . '/app_behat_runtime.js')); // Wait until the site login field appears OR the main page. $situation = $this->spin( - function($context, $args) { + function($context) use ($islegacy) { $page = $context->getSession()->getPage(); $element = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); if ($element) { // Wait for the onboarding modal to open, if any. $this->wait_for_pending_js(); - $element = $page->find('xpath', '//page-core-login-site-onboarding'); + $element = $islegacy + ? $page->find('xpath', '//page-core-login-site-onboarding') + : $page->find('xpath', '//core-login-site-onboarding'); if ($element) { $this->i_press_in_the_app('Skip'); + $this->wait_for_pending_js(); } return 'login'; @@ -327,7 +368,7 @@ class behat_app extends behat_base { // page. If it's the main page, we just leave it there. if ($situation === 'login') { $this->i_set_the_field_in_the_app('campus.example.edu', $CFG->wwwroot); - $this->i_press_in_the_app('Connect!'); + $this->i_press_in_the_app($islegacy ? 'Connect!' : 'Connect to your site'); } // Continue only after JS finishes. @@ -491,18 +532,23 @@ class behat_app extends behat_base { * @throws ExpectationException If the header text is different to the expected value */ public function the_header_should_be_in_the_app(string $text) { - $result = $this->spin(function($context, $args) { + $this->spin(function() use ($text) { $result = $this->evaluate_script('return window.behat.getHeader();'); + if (substr($result, 0, 3) !== 'OK:') { throw new DriverException('Error getting header - ' . $result); } - return $result; + + $header = substr($result, 3); + if (trim($header) !== trim($text)) { + throw new ExpectationException( + "The header text was not as expected: '$header'", + $this->getSession()->getDriver() + ); + } + + return true; }); - $header = substr($result, 3); - if (trim($header) !== trim($text)) { - throw new ExpectationException('The header text was not as expected: \'' . $header . '\'', - $this->getSession()->getDriver()); - } } /** From 778298a45582d3bce64aa8f359f0c627d768555c Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 29 Apr 2021 13:40:42 +0200 Subject: [PATCH 104/220] MOBILE-3738 behat: Implement navigation tests --- tests/behat/app_behat_runtime.js | 124 ++++++++++++++++++++-------- tests/behat/behat_app.php | 34 ++++++++ tests/behat/navigation.feature | 133 +++++++++++++++++++++++++++++++ 3 files changed, 257 insertions(+), 34 deletions(-) create mode 100644 tests/behat/navigation.feature diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index c725827f5..9a0e4bff2 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -194,6 +194,24 @@ return isElementVisible(element.parentElement, container); }; + /** + * Check if an element is selected. + * + * @param {HTMLElement} element Element + * @param {HTMLElement} container Container + * @returns {boolean} Whether the element is selected or not + */ + var isElementSelected = (element, container) => { + const ariaCurrent = element.getAttribute('aria-current'); + if (ariaCurrent && ariaCurrent !== 'false') + return true; + + if (!element.parentElement || element.parentElement === container) + return false; + + return isElementSelected(element.parentElement, container); + }; + /** * Generic shared function to find possible xpath matches within the document, that are visible, * and then process them using a callback function. @@ -330,43 +348,61 @@ */ var behatPressStandard = function(button) { log('Action - Click standard button: ' + button); - var selector; - switch (button) { - case 'back' : - selector = 'ion-navbar > button.back-button-md'; - break; - case 'main menu' : - // Change in app version 3.8. - selector = 'page-core-mainmenu .tab-button > ion-icon[aria-label=more], ' + - 'page-core-mainmenu .tab-button > ion-icon[aria-label=menu]'; - break; - case 'page menu' : - // This lang string was changed in app version 3.6. - selector = 'core-context-menu > button[aria-label=Info], ' + - 'core-context-menu > button[aria-label=Information], ' + - 'core-context-menu > button[aria-label="Display options"]'; - break; - default: - return 'ERROR: Unsupported standard button type'; - } - var buttons = Array.from(document.querySelectorAll(selector)); + + // Find button var foundButton = null; - var tooMany = false; - buttons.forEach(function(button) { - if (button.offsetParent) { - if (foundButton === null) { - foundButton = button; - } else { - tooMany = true; - } + + if (window.BehatMoodleAppLegacy) { + var selector; + switch (button) { + case 'back' : + selector = 'ion-navbar > button.back-button-md'; + break; + case 'main menu' : + // Change in app version 3.8. + selector = 'page-core-mainmenu .tab-button > ion-icon[aria-label=more], ' + + 'page-core-mainmenu .tab-button > ion-icon[aria-label=menu]'; + break; + case 'page menu' : + // This lang string was changed in app version 3.6. + selector = 'core-context-menu > button[aria-label=Info], ' + + 'core-context-menu > button[aria-label=Information], ' + + 'core-context-menu > button[aria-label="Display options"]'; + break; + default: + return 'ERROR: Unsupported standard button type'; + } + var buttons = Array.from(document.querySelectorAll(selector)); + var tooMany = false; + buttons.forEach(function(button) { + if (button.offsetParent) { + if (foundButton === null) { + foundButton = button; + } else { + tooMany = true; + } + } + }); + if (!foundButton) { + return 'ERROR: Could not find button'; + } + if (tooMany) { + return 'ERROR: Found too many buttons'; + } + } else { + switch (button) { + case 'back': + foundButton = findElementBasedOnText('Back'); + break; + case 'main menu': + foundButton = findElementBasedOnText('more', 'Notifications'); + break; + default: + return 'ERROR: Unsupported standard button type'; } - }); - if (!foundButton) { - return 'ERROR: Could not find button'; - } - if (tooMany) { - return 'ERROR: Found too many buttons'; } + + // Click button foundButton.click(); // Mark busy until the button click finishes processing. @@ -449,6 +485,25 @@ return window.appProvider.appCtrl.getRootNavs()[0]; }; + /** + * Check whether an item is selected or not. + * + * @param {string} text Text (full or partial) + * @param {string} near Optional 'near' text + * @return {string} YES or NO if successful, or ERROR: followed by message + */ + var behatIsSelected = function(text, near) { + log(`Action - Is Selected: "${text}"${near ? ` near "${near}"`: ''}`); + + try { + const element = findElementBasedOnText(text, near); + + return isElementSelected(element, document.body) ? 'YES' : 'NO'; + } catch (error) { + return 'ERROR: ' + error.message; + } + } + /** * Function to press arbitrary item based on its text or Aria label. * @@ -639,6 +694,7 @@ pressStandard : behatPressStandard, closePopup : behatClosePopup, find : behatFind, + isSelected : behatIsSelected, press : behatPress, setField : behatSetField, getHeader : behatGetHeader, diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index c1c14c80b..8eec8fd7b 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -120,6 +120,40 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } + /** + * Check if elements are selected in the app. + * + * @Then /^"(?P(?:[^"]|\\")*)"(?: near "(?P(?:[^"]|\\")*)")? should(?P not)? be selected in the app$/ + * @param string $text + */ + public function be_selected_in_the_app($text, $near='', $not='') { + $not = !empty($not); + $text = addslashes_js($text); + $near = addslashes_js($near); + + $this->spin(function() use ($not, $text, $near) { + $result = $this->evaluate_script("return window.behat.isSelected(\"$text\", \"$near\");"); + + switch ($result) { + case 'YES': + if ($not) { + throw new ExpectationException("Item was selected and shouldn't have", $this->getSession()->getDriver()); + } + break; + case 'NO': + if (!$not) { + throw new ExpectationException("Item wasn't selected and should have", $this->getSession()->getDriver()); + } + break; + default: + throw new DriverException('Error finding item - ' . $result); + } + + return true; + }); + $this->wait_for_pending_js(); + } + /** * Checks the Behat setup - tags and configuration. * diff --git a/tests/behat/navigation.feature b/tests/behat/navigation.feature new file mode 100644 index 000000000..5a02138e5 --- /dev/null +++ b/tests/behat/navigation.feature @@ -0,0 +1,133 @@ +@app @javascript +Feature: It navigates properly between pages. + + Background: + Given the following "users" exist: + | username | + | student1 | + Given the following "courses" exist: + | fullname | shortname | + | Course 2 | C2 | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | student1 | C2 | student | + And the following "grade categories" exist: + | fullname | course | + | Grade category C1 | C1 | + | Grade category C2 | C2 | + And the following "grade items" exist: + | gradecategory | itemname | grademin | grademax | course | + | Grade category C1 | Grade item C1 | 20 | 40 | C1 | + | Grade category C2 | Grade item C2 | 60 | 80 | C2 | + + Scenario: Navigate between split-view items in mobiles + + # Open more tab + Given I enter the app + And I log in as "student1" + And I press the main menu button in the app + + # Open grades tab + When I press "Grades" in the app + Then the header should be "Grades" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + + # Open C1 course grades + When I press "Course 1" in the app + Then the header should be "Grades" in the app + And I should find "Grade category C1" in the app + + # Open C1 grade item + When I press "Grade item C1" in the app + Then the header should be "Grade" in the app + And I should find "20" near "Range" in the app + And I should find "40" near "Range" in the app + + # Go back to course grades + When I press the back button in the app + Then the header should be "Grades" in the app + And I should find "Grade category C1" in the app + + # Go back to grades tab + When I press the back button in the app + Then the header should be "Grades" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + + # Open C2 course grades + When I press "Course 2" in the app + Then the header should be "Grades" in the app + And I should find "Grade category C2" in the app + + # Open C2 grade item + When I press "Grade item C2" in the app + Then the header should be "Grade" in the app + And I should find "60" near "Range" in the app + And I should find "80" near "Range" in the app + + # Go back to course grades + When I press the back button in the app + Then the header should be "Grades" in the app + And I should find "Grade category C2" in the app + + # Go back to grades tab + When I press the back button in the app + Then the header should be "Grades" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + + # Go back to more tab + When I press the back button in the app + Then I should find "Grades" in the app + And I should find "App settings" in the app + But I should not find "Back" in the app + + Scenario: Navigate between split-view items in tablets + + # Open more tab + Given I enter the app + And I change viewport size to "1200x640" + And I log in as "student1" + + # Open grades tab + When I press "Grades" in the app + Then the header should be "Grades" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Grade category C1" in the app + + # Open C1 course grades + When I press "Grade item C1" in the app + Then the header should be "Grades" in the app + And I should find "Grade category C1" in the app + And I should find "20" near "Range" in the app + And I should find "40" near "Range" in the app + + # Go back to grades tab + When I press the back button in the app + Then the header should be "Grades" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + + # Select C2 course + When I press "Course 2" in the app + Then the header should be "Grades" in the app + And "Course 2" should be selected in the app + And I should find "Grade category C2" in the app + + # Open C2 course grades + When I press "Grade item C2" in the app + Then the header should be "Grades" in the app + And I should find "Grade category C2" in the app + And I should find "60" near "Range" in the app + And I should find "80" near "Range" in the app + + # Go back to grades tab + When I press the back button in the app + Then the header should be "Grades" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + But I should not find "Back" in the app From d7593ab5c1347aee0306e472fd1ec29b599c4554 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 6 May 2021 13:06:25 +0200 Subject: [PATCH 105/220] MOBILE-3320 runtime: Ignore invalid nodes in find --- tests/behat/app_behat_runtime.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 9a0e4bff2..1a244c42f 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -292,7 +292,13 @@ if (currentNode.shadowRoot) { for (const childNode of currentNode.shadowRoot.childNodes) { - if (!childNode) { + if ( + !(childNode instanceof HTMLElement) || ( + childNode instanceof HTMLStyleElement || + childNode instanceof HTMLLinkElement || + childNode instanceof HTMLScriptElement + ) + ) { continue; } From c530d031b6e9af64120601c685f71ce887f2d470 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 10 May 2021 13:15:07 +0200 Subject: [PATCH 106/220] MOBILE-3320 behat: Comment flaky test --- mod/forum/tests/behat/app_basic_usage.feature | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 175c4bb52..2b4ea94c9 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -181,31 +181,32 @@ Feature: Test basic usage of forum activity in app Then I should not see "Not sent" And I should not see "This Discussion has offline data to be synchronised" - @app @3.8.0 - Scenario: Edit a not sent new discussion offline - When I enter the app - And I log in as "student1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - And I switch offline mode to "true" - And I press "Add a new discussion topic" in the app - And I set the field "Subject" to "Auto-test" in the app - And I set the field "Message" to "Auto-test message" in the app - And I press "Post to forum" in the app - And I press "Auto-test" in the app - And I set the field "Message" to "Auto-test message edited" in the app - And I press "Post to forum" in the app - Then I should see "This Forum has offline data to be synchronised." +# TODO Fix flaky test. +# @app @3.8.0 +# Scenario: Edit a not sent new discussion offline +# When I enter the app +# And I log in as "student1" +# And I press "Course 1" near "Course overview" in the app +# And I press "Test forum name" in the app +# And I switch offline mode to "true" +# And I press "Add a new discussion topic" in the app +# And I set the field "Subject" to "Auto-test" in the app +# And I set the field "Message" to "Auto-test message" in the app +# And I press "Post to forum" in the app +# And I press "Auto-test" in the app +# And I set the field "Message" to "Auto-test message edited" in the app +# And I press "Post to forum" in the app +# Then I should see "This Forum has offline data to be synchronised." - When I switch offline mode to "false" - And I press "Auto-test" in the app - Then I should see "Post to forum" +# When I switch offline mode to "false" +# And I press "Auto-test" in the app +# Then I should see "Post to forum" - When I press "Post to forum" in the app - Then I should not see "This Forum has offline data to be synchronised." +# When I press "Post to forum" in the app +# Then I should not see "This Forum has offline data to be synchronised." - When I press "Auto-test" near "Sort by last post creation date in descending order" in the app - And I should see "Auto-test message edited" +# When I press "Auto-test" near "Sort by last post creation date in descending order" in the app +# And I should see "Auto-test message edited" @app @3.8.0 Scenario: Edit a forum post (only online) From 31fa467ff97a017a13786937443a02a61e92b29e Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 11 May 2021 18:54:18 +0200 Subject: [PATCH 107/220] MOBILE-3320 behat: Push notifications navigation --- mod/course/tests/behat/app_courselist.feature | 5 +- tests/behat/app_behat_runtime.js | 164 ++++++++++-------- tests/behat/behat_app.php | 33 +++- .../navigation_pushnotifications.feature | 42 +++++ ...n.feature => navigation_splitview.feature} | 8 +- 5 files changed, 175 insertions(+), 77 deletions(-) create mode 100644 tests/behat/navigation_pushnotifications.feature rename tests/behat/{navigation.feature => navigation_splitview.feature} (95%) diff --git a/mod/course/tests/behat/app_courselist.feature b/mod/course/tests/behat/app_courselist.feature index 7a508f9f3..fc8adab44 100644 --- a/mod/course/tests/behat/app_courselist.feature +++ b/mod/course/tests/behat/app_courselist.feature @@ -93,7 +93,10 @@ Feature: Test course list shown on app start tab When I press "Display options" near "Course overview" in the app And I press "Filter my courses" in the app - And I set the field "Filter my courses" to "fr" in the app + + # TODO field should be "Filter my courses" + And I set the field "search text" to "fr" in the app + Then I should find "C3" in the app And I should find "C4" in the app And I should find "Frog 3" in the app diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 1a244c42f..e5c99e3f9 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -203,7 +203,10 @@ */ var isElementSelected = (element, container) => { const ariaCurrent = element.getAttribute('aria-current'); - if (ariaCurrent && ariaCurrent !== 'false') + if ( + (ariaCurrent && ariaCurrent !== 'false') || + (element.getAttribute('aria-selected') === 'true') + ) return true; if (!element.parentElement || element.parentElement === container) @@ -238,18 +241,21 @@ }; /** - * Finds an element within a given container. + * Finds elements within a given container. * * @param {HTMLElement} container Parent element to search the element within * @param {string} text Text to look for - * @return {HTMLElement} Found element + * @return {HTMLElement} Elements containing the given text */ - var findElementBasedOnTextWithin = (container, text) => { + var findElementsBasedOnTextWithin = (container, text) => { + const elements = []; const attributesSelector = `[aria-label*="${text}"], a[title*="${text}"], img[alt*="${text}"]`; for (const foundByAttributes of container.querySelectorAll(attributesSelector)) { - if (isElementVisible(foundByAttributes, container)) - return foundByAttributes; + if (!isElementVisible(foundByAttributes, container)) + continue; + + elements.push(foundByAttributes); } const treeWalker = document.createTreeWalker( @@ -280,15 +286,18 @@ while (currentNode = treeWalker.nextNode()) { if (currentNode instanceof Text) { if (currentNode.textContent.includes(text)) { - return currentNode.parentElement; + elements.push(currentNode.parentElement); } continue; } const labelledBy = currentNode.getAttribute('aria-labelledby'); - if (labelledBy && container.querySelector(`#${labelledBy}`)?.innerText?.includes(text)) - return currentNode; + if (labelledBy && container.querySelector(`#${labelledBy}`)?.innerText?.includes(text)) { + elements.push(currentNode); + + continue; + } if (currentNode.shadowRoot) { for (const childNode of currentNode.shadowRoot.childNodes) { @@ -303,47 +312,51 @@ } if (childNode.matches(attributesSelector)) { - return childNode; + elements.push(childNode); + + continue; } - const foundByText = findElementBasedOnTextWithin(childNode, text); - - if (foundByText) { - return foundByText; - } + elements.push(...findElementsBasedOnTextWithin(childNode, text)); } } } + + return elements; }; /** - * Function to find an element based on its text or Aria label. + * Function to find elements based on their text or Aria label. * * @param {string} text Text (full or partial) * @param {string} [near] Optional 'near' text - if specified, must have a single match on page - * @return {HTMLElement} Found element + * @return {HTMLElement} Found elements */ - var findElementBasedOnText = function(text, near) { + var findElementsBasedOnText = function(text, near) { const topContainer = document.querySelector('ion-alert, ion-popover, ion-action-sheet, core-ion-tab.show-tab ion-page.show-page, ion-page.show-page, html'); let container = topContainer; if (topContainer && near) { - const nearElement = findElementBasedOnText(near); + const nearElements = findElementsBasedOnText(near); - if (!nearElement) { - return; + if (nearElements.length === 0) { + throw new Error('There was no match for near text') + } else if (nearElements.length > 1) { + throw new Error('Too many matches for near text'); } - container = nearElement.parentElement; + container = nearElements[0].parentElement; } do { - const node = findElementBasedOnTextWithin(container, text); + const elements = findElementsBasedOnTextWithin(container, text); - if (node) { - return node; + if (elements.length > 0) { + return elements; } } while ((container = container.parentElement) && container !== topContainer); + + return []; }; /** @@ -398,10 +411,10 @@ } else { switch (button) { case 'back': - foundButton = findElementBasedOnText('Back'); + foundButton = findElementsBasedOnText('Back')[0]; break; case 'main menu': - foundButton = findElementBasedOnText('more', 'Notifications'); + foundButton = findElementsBasedOnText('more', 'Notifications')[0]; break; default: return 'ERROR: Unsupported standard button type'; @@ -462,7 +475,7 @@ log(`Action - Find ${text}`); try { - const element = findElementBasedOnText(text, near); + const element = findElementsBasedOnText(text, near)[0]; if (!element) { return 'ERROR: No matches for text'; @@ -502,7 +515,7 @@ log(`Action - Is Selected: "${text}"${near ? ` near "${near}"`: ''}`); try { - const element = findElementBasedOnText(text, near); + const element = findElementsBasedOnText(text, near)[0]; return isElementSelected(element, document.body) ? 'YES' : 'NO'; } catch (error) { @@ -522,7 +535,7 @@ var found; try { - found = findElementBasedOnText(text, near); + found = findElementsBasedOnText(text, near)[0]; if (!found) { return 'ERROR: No matches for text'; @@ -603,51 +616,60 @@ var behatSetField = function(field, value) { log('Action - Set field ' + field + ' to: ' + value); - // Find input(s) with given placeholder. - var escapedText = field.replace('"', '""'); - var exactMatches = []; - var anyMatches = []; - findPossibleMatches( - '//input[contains(@placeholder, "' + escapedText + '")] |' + - '//textarea[contains(@placeholder, "' + escapedText + '")] |' + - '//core-rich-text-editor/descendant::div[contains(@data-placeholder-text, "' + - escapedText + '")]', function(match) { - // Add to array depending on if it's an exact or partial match. - var placeholder; - if (match.nodeName === 'DIV') { - placeholder = match.getAttribute('data-placeholder-text'); - } else { - placeholder = match.getAttribute('placeholder'); - } - if (placeholder.trim() === field) { - exactMatches.push(match); - } else { - anyMatches.push(match); - } - }); + if (window.BehatMoodleAppLegacy) { + // Find input(s) with given placeholder. + var escapedText = field.replace('"', '""'); + var exactMatches = []; + var anyMatches = []; + findPossibleMatches( + '//input[contains(@placeholder, "' + escapedText + '")] |' + + '//textarea[contains(@placeholder, "' + escapedText + '")] |' + + '//core-rich-text-editor/descendant::div[contains(@data-placeholder-text, "' + + escapedText + '")]', function(match) { + // Add to array depending on if it's an exact or partial match. + var placeholder; + if (match.nodeName === 'DIV') { + placeholder = match.getAttribute('data-placeholder-text'); + } else { + placeholder = match.getAttribute('placeholder'); + } + if (placeholder.trim() === field) { + exactMatches.push(match); + } else { + anyMatches.push(match); + } + }); - // Select the resulting match. - var found = null; - do { - // If there is an exact text match, use that (regardless of other matches). - if (exactMatches.length > 1) { - return 'ERROR: Too many exact placeholder matches for text'; - } else if (exactMatches.length) { - found = exactMatches[0]; - break; + // Select the resulting match. + var found = null; + do { + // If there is an exact text match, use that (regardless of other matches). + if (exactMatches.length > 1) { + return 'ERROR: Too many exact placeholder matches for text'; + } else if (exactMatches.length) { + found = exactMatches[0]; + break; + } + + // If there is one partial text match, use that. + if (anyMatches.length > 1) { + return 'ERROR: Too many partial placeholder matches for text'; + } else if (anyMatches.length) { + found = anyMatches[0]; + break; + } + } while (false); + + if (!found) { + return 'ERROR: No matches for text'; } + } else { + const elements = findElementsBasedOnText(field); + var found = elements.filter(element => element.matches('input, textarea'))[0]; - // If there is one partial text match, use that. - if (anyMatches.length > 1) { - return 'ERROR: Too many partial placeholder matches for text'; - } else if (anyMatches.length) { - found = anyMatches[0]; - break; + if (!found) { + return 'ERROR: No matches for text'; } - } while (false); - - if (!found) { - return 'ERROR: No matches for text'; } // Functions to get/set value depending on field type. diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 8eec8fd7b..405ac532c 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -27,6 +27,7 @@ require_once(__DIR__ . '/../../../../lib/behat/behat_base.php'); +use Behat\Gherkin\Node\TableNode; use Behat\Mink\Exception\DriverException; use Behat\Mink\Exception\ExpectationException; @@ -401,7 +402,7 @@ class behat_app extends behat_base { // If it's the login page, we automatically fill in the URL and leave it on the user/pass // page. If it's the main page, we just leave it there. if ($situation === 'login') { - $this->i_set_the_field_in_the_app('campus.example.edu', $CFG->wwwroot); + $this->i_set_the_field_in_the_app($islegacy ? 'campus.example.edu' : 'Your site', $CFG->wwwroot); $this->i_press_in_the_app($islegacy ? 'Connect!' : 'Connect to your site'); } @@ -456,6 +457,36 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } + /** + * Receives push notifications for forum events. + * + * @Given /^I receive a forum push notification for:$/ + * @param TableNode $data + */ + public function i_receive_a_forum_push_notification(TableNode $data) { + global $DB, $CFG; + + $data = (object) $data->getColumnsHash()[0]; + $module = $DB->get_record('course_modules', ['idnumber' => $data->module]); + $discussion = $DB->get_record('forum_discussions', ['name' => $data->discussion]); + $notification = json_encode([ + 'site' => md5($CFG->wwwroot . $data->username), + 'courseid' => $discussion->course, + 'moodlecomponent' => 'mod_forum', + 'name' => 'posts', + 'contexturl' => '', + 'notif' => 1, + 'customdata' => [ + 'discussionid' => $discussion->id, + 'cmid' => $module->id, + 'instance' => $discussion->forum, + ], + ]); + + $this->evaluate_script("return window.pushNotifications.notificationClicked($notification)"); + $this->wait_for_pending_js(); + } + /** * Closes a popup by clicking on the 'backdrop' behind it. * diff --git a/tests/behat/navigation_pushnotifications.feature b/tests/behat/navigation_pushnotifications.feature new file mode 100644 index 000000000..d36002e0c --- /dev/null +++ b/tests/behat/navigation_pushnotifications.feature @@ -0,0 +1,42 @@ +@app @javascript +Feature: It navigates properly after receiving push notifications. + + Background: + Given the following "users" exist: + | username | + | student1 | + | student2 | + And the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | student2 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | forum | Test forum | Test forum | C1 | forum | + And the following forum discussions exist in course "Course 1": + | forum | user | name | message | + | Test forum | student1 | Forum topic | Forum message | + And the following config values are set as admin: + | forcelogout | 1 | tool_mobile | + + Scenario: Open a forum push notification + When I enter the app + And I log in as "student2" + And I press the main menu button in the app + And I press "Log out" in the app + And I press "Add" in the app + And I set the field "Your site" to "$WWWROOT" in the app + And I press "Connect to your site" in the app + And I log in as "student1" + And I receive a forum push notification for: + | username | course | module | discussion | + | student2 | C1 | forum | Forum topic | + Then I should find "Reconnect" in the app + + When I set the field "Password" to "student2" in the app + And I press "Log in" in the app + Then I should find "Forum topic" in the app + And I should find "Forum message" in the app diff --git a/tests/behat/navigation.feature b/tests/behat/navigation_splitview.feature similarity index 95% rename from tests/behat/navigation.feature rename to tests/behat/navigation_splitview.feature index 5a02138e5..78ecda825 100644 --- a/tests/behat/navigation.feature +++ b/tests/behat/navigation_splitview.feature @@ -1,11 +1,11 @@ @app @javascript -Feature: It navigates properly between pages. +Feature: It navigates properly in pages with a split-view component. Background: Given the following "users" exist: | username | | student1 | - Given the following "courses" exist: + And the following "courses" exist: | fullname | shortname | | Course 2 | C2 | | Course 1 | C1 | @@ -22,7 +22,7 @@ Feature: It navigates properly between pages. | Grade category C1 | Grade item C1 | 20 | 40 | C1 | | Grade category C2 | Grade item C2 | 60 | 80 | C2 | - Scenario: Navigate between split-view items in mobiles + Scenario: Navigate in grades tab on mobile # Open more tab Given I enter the app @@ -85,7 +85,7 @@ Feature: It navigates properly between pages. And I should find "App settings" in the app But I should not find "Back" in the app - Scenario: Navigate between split-view items in tablets + Scenario: Navigate in grades tab on tablet # Open more tab Given I enter the app From e661fa3fa79571bd326bc96dc5712fe8faf8b20b Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 18 May 2021 15:53:31 +0200 Subject: [PATCH 108/220] MOBILE-3320 behat: Test messages settings --- mod/messages/tests/behat/settings.feature | 18 +++++++++++ tests/behat/app_behat_runtime.js | 3 +- tests/behat/behat_app.php | 38 ++++++++++++----------- 3 files changed, 40 insertions(+), 19 deletions(-) create mode 100644 mod/messages/tests/behat/settings.feature diff --git a/mod/messages/tests/behat/settings.feature b/mod/messages/tests/behat/settings.feature new file mode 100644 index 000000000..227ddfc1a --- /dev/null +++ b/mod/messages/tests/behat/settings.feature @@ -0,0 +1,18 @@ +@mod @mod_messages @app @javascript +Feature: Test messages settings + + Background: + Given the following "users" exist: + | username | + | student1 | + + Scenario: Modify settings + When I enter the app + And I log in as "student1" + And I press "Messages" in the app + And I press "Message preferences" in the app + And I select "My contacts only" in the app + Then "My contacts only" should be selected in the app + + And I select "My contacts and anyone in my courses" in the app + Then "My contacts and anyone in my courses" should be selected in the app diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index e5c99e3f9..a3e542f80 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -205,7 +205,8 @@ const ariaCurrent = element.getAttribute('aria-current'); if ( (ariaCurrent && ariaCurrent !== 'false') || - (element.getAttribute('aria-selected') === 'true') + (element.getAttribute('aria-selected') === 'true') || + (element.getAttribute('aria-checked') === 'true') ) return true; diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 405ac532c..c2b753d0a 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -423,7 +423,7 @@ class behat_app extends behat_base { // Note there are two 'Log in' texts visible (the title and the button) so we have to use // a 'near' value here. - $this->i_press_near_in_the_app('Log in', 'Forgotten'); + $this->i_press_in_the_app('Log in', 'Forgotten'); // Wait until the main page appears. $this->spin( @@ -510,27 +510,29 @@ class behat_app extends behat_base { * Note it is difficult to use the standard 'click on' or 'press' steps because those do not * distinguish visible items and the app always has many non-visible items in the DOM. * - * @Given /^I press "(?P(?:[^"]|\\")*)" in the app$/ - * @param string $text Text identifying click target - * @throws DriverException If the press doesn't work - */ - public function i_press_in_the_app(string $text) { - $this->press($text); - } - - /** - * Clicks on / touches something that is visible in the app, near some other text. - * - * This is the same as the other step, but when there are multiple matches, it picks the one - * nearest (in DOM terms) the second text. The second text should be an exact match, or a partial - * match that only has one result. - * - * @Given /^I press "(?P(?:[^"]|\\")*)" near "(?P(?:[^"]|\\")*)" in the app$/ + * @Then /^I press "(?P(?:[^"]|\\")*)"(?: near "(?P(?:[^"]|\\")*)")? in the app$/ * @param string $text Text identifying click target * @param string $near Text identifying a nearby unique piece of text * @throws DriverException If the press doesn't work */ - public function i_press_near_in_the_app(string $text, string $near) { + public function i_press_in_the_app($text, $near='') { + $this->press($text, $near); + } + + /** + * Select an item from a list of options, such as a radio button. + * + * It may be necessary to use this step instead of "I press..." because radio buttons in Ionic are initialized + * with JavaScript, and clicks may not work until they are initialized properly which may cause flaky tests due + * to race conditions. + * + * @Then /^I select "(?P(?:[^"]|\\")*)"(?: near "(?P(?:[^"]|\\")*)")? in the app$/ + * @param string $text Text identifying click target + * @param string $near Text identifying a nearby unique piece of text + * @throws DriverException If the press doesn't work + */ + public function i_select_in_the_app($text, $near='') { + $this->getSession()->wait(100); $this->press($text, $near); } From 0e4e25d3c1d14c7e70748bc090781f70d6df8436 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 20 May 2021 11:20:50 +0200 Subject: [PATCH 109/220] MOBILE-3751 behat: Add heading page selector --- tests/behat/app_behat_runtime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index a3e542f80..7da3164a0 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -585,7 +585,7 @@ var result = null; var resultCount = 0; - var titles = Array.from(document.querySelectorAll('ion-header ion-title')); + var titles = Array.from(document.querySelectorAll('ion-header ion-title, ion-header h1')); titles.forEach(function(title) { if ( (window.BehatMoodleAppLegacy && title.offsetParent) || From ae0af40b10f72b4679748d797e6c9915c7064451 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 26 May 2021 17:09:09 +0200 Subject: [PATCH 110/220] MOBILE-3320 behat: Extract app launch step --- tests/behat/behat_app.php | 157 +++++++++++++++++++++++--------------- 1 file changed, 96 insertions(+), 61 deletions(-) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index c2b753d0a..b5abee45e 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -46,6 +46,9 @@ class behat_app extends behat_base { /** @var string URL for running Ionic server */ protected $ionicurl = ''; + /** @var bool Checks whether the app is runing a legacy version (ionic 3) */ + protected $islegacy; + /** * Checks if the current OS is Windows, from the point of view of task-executing-and-killing. * @@ -67,9 +70,7 @@ class behat_app extends behat_base { } /** - * Opens the Moodle app in the browser. - * - * Requires JavaScript. + * Opens the Moodle app in the browser and introduces the enters the site. * * @Given /^I enter the app$/ * @throws DriverException Issue with configuration or feature file @@ -77,28 +78,35 @@ class behat_app extends behat_base { * @throws ExpectationException Problem with resizing window */ public function i_enter_the_app() { + $this->i_launch_the_app(); + $this->enter_site(); + } + + /** + * Opens the Moodle app in the browser. + * + * @Given /^I launch the app$/ + * @throws DriverException Issue with configuration or feature file + * @throws dml_exception Problem with Moodle setup + * @throws ExpectationException Problem with resizing window + */ + public function i_launch_the_app() { // Check the app tag was set. if (!$this->has_tag('app')) { throw new DriverException('Requires @app tag on scenario or feature.'); } - // Restart the browser and set its size. - $this->getSession()->restart(); - $this->resize_window('360x720', true); - - if (empty($this->ionicurl)) { - $this->ionicurl = $this->start_or_reuse_ionic(); - } - // Go to page and prepare browser for app. - $this->prepare_browser($this->ionicurl); + $this->prepare_browser(); } /** * Finds elements in the app. * * @Then /^I should(?P not)? find "(?P(?:[^"]|\\")*)"(?: near "(?P(?:[^"]|\\")*)")? in the app$/ + * @param string $not * @param string $text + * @param string $near */ public function i_find_in_the_app($not, $text='', $near='') { $not = !empty($not); @@ -341,75 +349,92 @@ class behat_app extends behat_base { * @param string $url App URL * @throws DriverException If the app fails to load properly */ - protected function prepare_browser(string $url) { - global $CFG; + protected function prepare_browser() { + // Restart the browser and set its size. + $this->getSession()->restart(); + $this->resize_window('360x720', true); + + if (empty($this->ionicurl)) { + $this->ionicurl = $this->start_or_reuse_ionic(); + } // Check whether the app is running a legacy version. - $json = @file_get_contents("$url/assets/env.json") ?: @file_get_contents("$url/config.json"); + $json = @file_get_contents("{$this->ionicurl}/assets/env.json") ?: @file_get_contents("{$this->ionicurl}/config.json"); $data = json_decode($json); $appversion = $data->build->version ?? str_replace('-dev', '', $data->versionname); - $islegacy = version_compare($appversion, '3.9.5', '<'); + + $this->islegacy = version_compare($appversion, '3.9.5', '<'); // Visit the Ionic URL and wait for it to load. - $this->getSession()->visit($url); - $this->spin( - function($context) use ($islegacy) { - $title = $context->getSession()->getPage()->find('xpath', '//title'); - if ($title) { - $text = $title->getHtml(); - if ( - ($islegacy && $text === 'Moodle Desktop') || - (!$islegacy && $text === 'Moodle App') - ) { - return true; - } - } - throw new DriverException('Moodle app not found in browser'); - }, false, 60); + $this->getSession()->visit($this->ionicurl); + $this->spin(function($context) { + $title = $context->getSession()->getPage()->find('xpath', '//title'); + + if ($title) { + $text = $title->getHtml(); + + if ( + ($this->islegacy && $text === 'Moodle Desktop') || + (!$this->islegacy && $text === 'Moodle App') + ) { + return true; + } + } + + throw new DriverException('Moodle app not found in browser'); + }, false, 60); // Run the scripts to install Moodle 'pending' checks. - $islegacyboolean = $islegacy ? 'true' : 'false'; + $islegacyboolean = $this->islegacy ? 'true' : 'false'; $this->execute_script("window.BehatMoodleAppLegacy = $islegacyboolean;"); $this->execute_script(file_get_contents(__DIR__ . '/app_behat_runtime.js')); - // Wait until the site login field appears OR the main page. - $situation = $this->spin( - function($context) use ($islegacy) { - $page = $context->getSession()->getPage(); + // Assert initial page. + $this->spin(function($context) { + $page = $context->getSession()->getPage(); + $element = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); - $element = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); - if ($element) { - // Wait for the onboarding modal to open, if any. - $this->wait_for_pending_js(); - $element = $islegacy - ? $page->find('xpath', '//page-core-login-site-onboarding') - : $page->find('xpath', '//core-login-site-onboarding'); - if ($element) { - $this->i_press_in_the_app('Skip'); - $this->wait_for_pending_js(); - } + if ($element) { + // Wait for the onboarding modal to open, if any. + $this->wait_for_pending_js(); - return 'login'; - } + $element = $this->islegacy + ? $page->find('xpath', '//page-core-login-site-onboarding') + : $page->find('xpath', '//core-login-site-onboarding'); - $element = $page->find('xpath', '//page-core-mainmenu'); - if ($element) { - return 'mainpage'; - } - throw new DriverException('Moodle app login URL prompt not found'); - }, behat_base::get_extended_timeout(), 60); + if ($element) { + $this->i_press_in_the_app('Skip'); + } - // If it's the login page, we automatically fill in the URL and leave it on the user/pass - // page. If it's the main page, we just leave it there. - if ($situation === 'login') { - $this->i_set_the_field_in_the_app($islegacy ? 'campus.example.edu' : 'Your site', $CFG->wwwroot); - $this->i_press_in_the_app($islegacy ? 'Connect!' : 'Connect to your site'); - } + // Login screen found. + return true; + } + + if ($page->find('xpath', '//page-core-mainmenu')) { + // Main menu found. + return true; + } + + throw new DriverException('Moodle app not launched properly'); + }, false, 60); // Continue only after JS finishes. $this->wait_for_pending_js(); } + protected function enter_site() { + if (!$this->is_in_login_page()) { + // Already in the site. + return; + } + + global $CFG; + + $this->i_set_the_field_in_the_app($this->islegacy ? 'campus.example.edu' : 'Your site', $CFG->wwwroot); + $this->i_press_in_the_app($this->islegacy ? 'Connect!' : 'Connect to your site'); + $this->wait_for_pending_js(); + } + /** * Carries out the login steps for the app, assuming the user is on the app login page. Called * from behat_auth.php. @@ -536,6 +561,16 @@ class behat_app extends behat_base { $this->press($text, $near); } + /** + * Check whether the current page is the login form. + */ + protected function is_in_login_page(): bool { + $page = $this->getSession()->getPage(); + $logininput = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); + + return !is_null($logininput); + } + /** * Clicks on / touches something that is visible in the app, near some other text. * From 22497fe7cd8c94fa9fd7e9af51b22e92130450af Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 26 May 2021 17:09:47 +0200 Subject: [PATCH 111/220] MOBILE-3320 behat: Implement browser tab assertion --- tests/behat/behat_app.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index b5abee45e..3d52a63c5 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -653,6 +653,31 @@ class behat_app extends behat_base { }); } + /** + * Check that the app opened a new browser tab. + * + * @Given /^the app should(?P not)? have opened a browser tab$/ + * @param string $not + */ + public function the_app_should_have_opened_a_browser_tab($not = '') { + $not = !empty($not); + + $this->spin(function() use ($not) { + $openedbrowsertab = count($this->getSession()->getWindowNames()) === 2; + + if ($not === $openedbrowsertab) { + throw new ExpectationException( + $not + ? 'Did not expect the app to have opened a browser tab' + : 'Expected the app to have opened a browser tab', + $this->getSession()->getDriver() + ); + } + + return true; + }); + } + /** * Switches to a newly-opened browser tab. * From 4673ddd03ed9b383544e48bbe7afa803899ccd92 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 27 May 2021 18:11:52 +0200 Subject: [PATCH 112/220] MOBILE-3320 behat: Update choice tests --- .../tests/behat/app_basic_usage.feature | 137 +++++++++--------- tests/behat/app_behat_runtime.js | 38 ++++- 2 files changed, 104 insertions(+), 71 deletions(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 22ea6aa69..a25265feb 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_choice @app @app_upto3.9.4 @javascript +@mod @mod_choice @app @javascript Feature: Test basic usage of choice activity in app In order to participate in the choice while using the mobile app As a student @@ -17,7 +17,6 @@ Feature: Test basic usage of choice activity in app | teacher1 | C1 | editingteacher | | student1 | C1 | student | - @app @3.8.0 Scenario: Answer a choice (multi or single, update answer) & View results Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | @@ -26,24 +25,23 @@ Feature: Test basic usage of choice activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test single choice name" in the app - And I press "Option 1" in the app - And I press "Option 2" in the app + And I select "Option 1" in the app + And I select "Option 2" in the app And I press "Save my choice" in the app - Then I should see "Are you sure" + Then I should find "Are you sure" in the app When I press "OK" in the app - Then I should see "Option 1: 0" - And I should see "Option 2: 1" - And I should see "Option 3: 0" - But I should not see "Remove my choice" + Then I should find "Option 1: 0" in the app + And I should find "Option 2: 1" in the app + And I should find "Option 3: 0" in the app + But I should not find "Remove my choice" in the app When I press the back button in the app And I press "Test single choice name" in the app - Then I should see "Option 1: 0" - And I should see "Option 2: 1" - And I should see "Option 3: 0" + Then I should find "Option 1: 0" in the app + And I should find "Option 2: 1" in the app + And I should find "Option 3: 0" in the app - @app @3.8.0 Scenario: Answer a choice (multi or single, update answer) & View results & Delete choice Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | @@ -52,29 +50,28 @@ Feature: Test basic usage of choice activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test multi choice name" in the app - And I press "Option 1" in the app - And I press "Option 2" in the app + And I select "Option 1" in the app + And I select "Option 2" in the app And I press "Save my choice" in the app - Then I should see "Option 1: 1" - And I should see "Option 2: 1" - And I should see "Option 3: 0" - And I should see "Remove my choice" + Then I should find "Option 1: 1" in the app + And I should find "Option 2: 1" in the app + And I should find "Option 3: 0" in the app + And I should find "Remove my choice" in the app - When I press "Option 1" in the app - And I press "Option 3" in the app + When I select "Option 1" in the app + And I select "Option 3" in the app And I press "Save my choice" in the app - Then I should see "Option 1: 0" - And I should see "Option 2: 1" - And I should see "Option 3: 1" + Then I should find "Option 1: 0" in the app + And I should find "Option 2: 1" in the app + And I should find "Option 3: 1" in the app When I press "Remove my choice" in the app - Then I should see "Are you sure" + Then I should find "Are you sure" in the app When I press "Delete" in the app - Then I should see "The results are not currently viewable" - But I should not see "Remove my choice" + Then I should find "The results are not currently viewable" in the app + But I should not find "Remove my choice" in the app - @app @3.8.0 Scenario: Answer and change answer offline & Sync choice Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | @@ -83,31 +80,32 @@ Feature: Test basic usage of choice activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test single choice name" in the app - And I press "Option 1" in the app + And I select "Option 1" in the app And I switch offline mode to "true" - And I press "Option 2" in the app + And I select "Option 2" in the app And I press "Save my choice" in the app - Then I should see "Are you sure" + Then I should find "Are you sure" in the app When I press "OK" in the app And I press the back button in the app And I press "Test single choice name" in the app - Then I should see "This Choice has offline data to be synchronised." - But I should not see "Option 1: 0" - And I should not see "Option 2: 1" - And I should not see "Option 3: 0" + Then I should find "This Choice has offline data to be synchronised." in the app + But I should not find "Option 1: 0" in the app + And I should not find "Option 2: 1" in the app + And I should not find "Option 3: 0" in the app When I switch offline mode to "false" And I press the back button in the app And I press "Test single choice name" in the app - And I press "Display options" in the app - And I press "Refresh" in the app - Then I should see "Option 1: 0" - And I should see "Option 2: 1" - And I should see "Option 3: 0" - But I should not see "This Choice has offline data to be synchronised." + Then I should find "Test single choice description" in the app + + When I press "Display options" in the app + And I press "Refresh" in the app + Then I should find "Option 1: 0" in the app + And I should find "Option 2: 1" in the app + And I should find "Option 3: 0" in the app + But I should not find "This Choice has offline data to be synchronised." in the app - @app @3.8.0 Scenario: Answer and change answer offline & Auto-sync choice Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | @@ -120,23 +118,22 @@ Feature: Test basic usage of choice activity in app And I switch offline mode to "true" And I press "Option 2" in the app And I press "Save my choice" in the app - Then I should see "Are you sure" + Then I should find "Are you sure" in the app When I press "OK" in the app - And I switch offline mode to "false" - Then I should see "This Choice has offline data to be synchronised." - But I should not see "Option 1: 0" - And I should not see "Option 2: 1" - And I should not see "Option 3: 0" + Then I should find "This Choice has offline data to be synchronised." in the app + But I should not find "Option 1: 0" in the app + And I should not find "Option 2: 1" in the app + And I should not find "Option 3: 0" in the app - When I run cron tasks in the app + When I switch offline mode to "false" + And I run cron tasks in the app And I wait loading to finish in the app - Then I should see "Option 1: 0" - And I should see "Option 2: 1" - And I should see "Option 3: 0" - But I should not see "This Choice has offline data to be synchronised." + Then I should find "Option 1: 0" in the app + And I should find "Option 2: 1" in the app + And I should find "Option 3: 0" in the app + But I should not find "This Choice has offline data to be synchronised." in the app - @app @3.8.0 Scenario: Prefetch Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | @@ -147,35 +144,36 @@ Feature: Test basic usage of choice activity in app And I press "Course 1" near "Course overview" in the app And I press "Display options" in the app And I press "Show download options" in the app - And I press "cloud download" near "Test single choice name" in the app - And I switch offline mode to "true" + And I press "Download" near "Test single choice name" in the app + Then I should find "Downloaded" near "Test single choice name" in the app + + When I switch offline mode to "true" And I press "Test multi choice name" in the app - Then I should see "There was a problem connecting to the site. Please check your connection and try again." + Then I should find "There was a problem connecting to the site. Please check your connection and try again." in the app When I press "OK" in the app And I press the back button in the app And I press "Test single choice name" in the app And I press "Option 2" in the app And I press "Save my choice" in the app - Then I should see "Are you sure" + Then I should find "Are you sure" in the app When I press "OK" in the app And I press the back button in the app And I press "Test single choice name" in the app - Then I should see "This Choice has offline data to be synchronised." - But I should not see "Option 1: 0" - And I should not see "Option 2: 1" - And I should not see "Option 3: 0" + Then I should find "This Choice has offline data to be synchronised." in the app + But I should not find "Option 1: 0" in the app + And I should not find "Option 2: 1" in the app + And I should not find "Option 3: 0" in the app When I switch offline mode to "false" And I press the back button in the app And I press "Test single choice name" in the app - Then I should see "Option 1: 0" - And I should see "Option 2: 1" - And I should see "Option 3: 0" - But I should not see "This Choice has offline data to be synchronised." + Then I should find "Option 1: 0" in the app + And I should find "Option 2: 1" in the app + And I should find "Option 3: 0" in the app + But I should not find "This Choice has offline data to be synchronised." in the app - @app @3.8.0 Scenario: Download students choice in text format # Submit answer as student Given the following "activities" exist: @@ -194,10 +192,13 @@ Feature: Test basic usage of choice activity in app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app And I press "Choice name" in the app - And I press "Display options" in the app + Then I should find "Test choice description" in the app + + When I press "Display options" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" And I press "Actions menu" And I follow "View 1 responses" And I press "Download in text format" + # TODO Then I should find "..." in the downloads folder diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 7da3164a0..db9f68695 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -326,6 +326,32 @@ return elements; }; + /** + * Given a list of elements, get the top ancestors among all of them. + * + * This will remote duplicates and drop any elements nested within each other. + * + * @param {Array} elements Elements list. + * @return {Array} Top ancestors. + */ + var getTopAncestors = function(elements) { + const uniqueElements = new Set(elements); + + for (const element of uniqueElements) { + for (otherElement of uniqueElements) { + if (otherElement === element) { + continue; + } + + if (element.contains(otherElement)) { + uniqueElements.delete(otherElement); + } + } + } + + return [...uniqueElements]; + }; + /** * Function to find elements based on their text or Aria label. * @@ -343,10 +369,16 @@ if (nearElements.length === 0) { throw new Error('There was no match for near text') } else if (nearElements.length > 1) { - throw new Error('Too many matches for near text'); - } + const nearElementsAncestors = getTopAncestors(nearElements); - container = nearElements[0].parentElement; + if (nearElementsAncestors.length > 1) { + throw new Error('Too many matches for near text'); + } + + container = nearElementsAncestors[0].parentElement; + } else { + container = nearElements[0].parentElement; + } } do { From d774b2f5e0dd8ad52dfcc4470fffd5c59d13f1a3 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 31 May 2021 16:39:45 +0200 Subject: [PATCH 113/220] MOBILE-3320 behat: Improve flaky tests --- .../tests/behat/app_basic_usage.feature | 10 ++-- tests/behat/behat_app.php | 58 +++++++++++++++---- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index a25265feb..6f0caea8e 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -58,7 +58,7 @@ Feature: Test basic usage of choice activity in app And I should find "Option 3: 0" in the app And I should find "Remove my choice" in the app - When I select "Option 1" in the app + When I unselect "Option 1" in the app And I select "Option 3" in the app And I press "Save my choice" in the app Then I should find "Option 1: 0" in the app @@ -114,9 +114,9 @@ Feature: Test basic usage of choice activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test single choice name" in the app - And I press "Option 1" in the app + And I select "Option 1" in the app And I switch offline mode to "true" - And I press "Option 2" in the app + And I select "Option 2" in the app And I press "Save my choice" in the app Then I should find "Are you sure" in the app @@ -154,7 +154,7 @@ Feature: Test basic usage of choice activity in app When I press "OK" in the app And I press the back button in the app And I press "Test single choice name" in the app - And I press "Option 2" in the app + And I select "Option 2" in the app And I press "Save my choice" in the app Then I should find "Are you sure" in the app @@ -183,7 +183,7 @@ Feature: Test basic usage of choice activity in app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Choice name" in the app - And I press "Option 2" in the app + And I select "Option 2" in the app And I press "Save my choice" in the app And I press "OK" in the app diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 3d52a63c5..1d995a6ba 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -551,14 +551,49 @@ class behat_app extends behat_base { * with JavaScript, and clicks may not work until they are initialized properly which may cause flaky tests due * to race conditions. * - * @Then /^I select "(?P(?:[^"]|\\")*)"(?: near "(?P(?:[^"]|\\")*)")? in the app$/ + * @Then /^I (?Punselect|select) "(?P(?:[^"]|\\")*)"(?: near "(?P(?:[^"]|\\")*)")? in the app$/ + * @param string $selectedtext Select/unselect string * @param string $text Text identifying click target * @param string $near Text identifying a nearby unique piece of text * @throws DriverException If the press doesn't work */ - public function i_select_in_the_app($text, $near='') { - $this->getSession()->wait(100); - $this->press($text, $near); + public function i_select_in_the_app(string $selectedtext, string $text, string $near = '') { + $selected = $selectedtext === 'select' ? 'YES' : 'NO'; + $text = addslashes_js($text); + $near = addslashes_js($near); + + $this->spin(function() use ($selectedtext, $selected, $text, $near) { + // Don't do anything if the item is already in the expected state. + $result = $this->evaluate_script("return window.behat.isSelected(\"$text\", \"$near\");"); + + if ($result === $selected) { + return true; + } + + // Press item. + $result = $this->evaluate_script("return window.behat.press(\"$text\", \"$near\");"); + + if ($result !== 'OK') { + throw new DriverException('Error pressing item - ' . $result); + } + + // Check that it worked as expected. + $result = $this->evaluate_script("return window.behat.isSelected(\"$text\", \"$near\");"); + + switch ($result) { + case 'YES': + case 'NO': + if ($result !== $selected) { + throw new ExpectationException("Item wasn't $selectedtext after pressing it", $this->getSession()->getDriver()); + } + + return true; + default: + throw new DriverException('Error finding item - ' . $result); + } + }); + + $this->wait_for_pending_js(); } /** @@ -584,17 +619,16 @@ class behat_app extends behat_base { * @throws DriverException If the press doesn't work */ protected function press(string $text, string $near = '') { - $this->spin(function($context, $args) use ($text, $near) { - if ($near !== '') { - $nearbit = ', "' . addslashes_js($near) . '"'; - } else { - $nearbit = ''; - } - $result = $this->evaluate_script('return window.behat.press("' . - addslashes_js($text) . '"' . $nearbit .');'); + $text = addslashes_js($text); + $near = addslashes_js($near); + + $this->spin(function() use ($text, $near) { + $result = $this->evaluate_script("return window.behat.press(\"$text\", \"$near\");"); + if ($result !== 'OK') { throw new DriverException('Error pressing item - ' . $result); } + return true; }); $this->wait_for_pending_js(); From 98e5a63eb69d5a0dc5c51506f42cfdda6f4c0921 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 1 Jun 2021 17:18:22 +0200 Subject: [PATCH 114/220] MOBILE-3320 behat: Update chat tests --- mod/chat/tests/behat/app_basic_usage.feature | 45 +++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/mod/chat/tests/behat/app_basic_usage.feature b/mod/chat/tests/behat/app_basic_usage.feature index 5838fa4ae..cd3ec9fbf 100755 --- a/mod/chat/tests/behat/app_basic_usage.feature +++ b/mod/chat/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_chat @app @app_upto3.9.4 @javascript +@mod @mod_chat @app @javascript Feature: Test basic usage of chat in app As a student I need basic chat functionality to work @@ -19,23 +19,24 @@ Feature: Test basic usage of chat in app | activity | name | intro | course | idnumber | groupmode | | chat | Test chat name | Test chat | C1 | chat | 0 | - @app @3.8.0 Scenario: Receive and send messages & See connected users, beep and talk to # Send messages as student1 When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test chat name" in the app - Then I should see "Click here to enter the chat now" - And I should see "View past chat sessions" + Then I should find "Click here to enter the chat now" in the app + And I should find "View past chat sessions" in the app When I press "Click here to enter the chat now" in the app - And I set the field "New message" to "Hi!" + And I set the field "New message" to "Hi!" in the app And I press "Send" in the app - And I set the field "New message" to "I am David" + Then I should find "Hi!" in the app + + When I set the field "New message" to "I am David" in the app And I press "Send" in the app - Then I should see "Hi!" - And I should see "I am David" + Then I should find "Hi!" in the app + And I should find "I am David" in the app # Read messages, view connected users, send beep and reply as student2 When I enter the app @@ -43,20 +44,19 @@ Feature: Test basic usage of chat in app And I press "Course 1" near "Course overview" in the app And I press "Test chat name" in the app And I press "Click here to enter the chat now" in the app - Then I should see "Hi!" - And I should see "I am David" + Then I should find "Hi!" in the app + And I should find "I am David" in the app - When I press "people" in the app - Then I should see "david student" + When I press "Users" in the app + Then I should find "david student" in the app When I press "Beep" in the app - Then I should see "You beeped david student" + Then I should find "You beeped david student" in the app - When I set the field "New message" to "Hi David, I am Pau." + When I set the field "New message" to "Hi David, I am Pau." in the app And I press "Send" in the app - Then I should see "Hi David, I am Pau." + Then I should find "Hi David, I am Pau." in the app - @app @3.8.0 Scenario: Past sessions shown for >=3.5 # Send messages as student1 Given I enter the app @@ -64,10 +64,13 @@ Feature: Test basic usage of chat in app And I press "Course 1" near "Course overview" in the app And I press "Test chat name" in the app And I press "Click here to enter the chat now" in the app - And I set the field "New message" to "Hi!" + And I set the field "New message" to "Hi!" in the app And I press "Send" in the app - And I set the field "New message" to "I am David" + Then I should find "Hi!" in the app + + When I set the field "New message" to "I am David" in the app And I press "Send" in the app + Then I should find "I am David" in the app # Read messages from past sessions as student2 When I enter the app @@ -76,6 +79,6 @@ Feature: Test basic usage of chat in app And I press "Test chat name" in the app And I press "View past chat sessions" in the app And I press "Show incomplete sessions" in the app - And I press "david student (2)" in the app - Then I should see "Hi!" - And I should see "I am David" + And I press "david student" near "(2)" in the app + Then I should find "Hi!" in the app + And I should find "I am David" in the app From 3ce506ea019df77b2b99fbe984cb7a8646dd895c Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 3 Jun 2021 11:20:36 +0200 Subject: [PATCH 115/220] MOBILE-3320 behat: Improve element locators --- tests/behat/app_behat_runtime.js | 87 ++++++++------ tests/behat/behat_app.php | 187 ++++++++++++++++++------------- 2 files changed, 156 insertions(+), 118 deletions(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index db9f68695..0f2ee103e 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -11,13 +11,13 @@ * * @param {string} text Information to log */ - var log = function(text) { + var log = function() { var now = new Date(); var nowFormatted = String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0') + ':' + String(now.getSeconds()).padStart(2, '0') + '.' + String(now.getMilliseconds()).padStart(2, '0'); - console.log('BEHAT: ' + nowFormatted + ' ' + text); // eslint-disable-line no-console + console.log('BEHAT: ' + nowFormatted, ...arguments); // eslint-disable-line no-console }; /** @@ -185,13 +185,14 @@ if (element.getAttribute('aria-hidden') === 'true' || getComputedStyle(element).display === 'none') return false; - if (element.parentElement === container) + const parentElement = getParentElement(element); + if (parentElement === container) return true; - if (!element.parentElement) + if (!parentElement) return false; - return isElementVisible(element.parentElement, container); + return isElementVisible(parentElement, container); }; /** @@ -210,10 +211,11 @@ ) return true; - if (!element.parentElement || element.parentElement === container) + const parentElement = getParentElement(element); + if (!parentElement || parentElement === container) return false; - return isElementSelected(element.parentElement, container); + return isElementSelected(parentElement, container); }; /** @@ -352,19 +354,28 @@ return [...uniqueElements]; }; + /** + * Get parent element, including Shadow DOM parents. + * + * @param {HTMLElement} element Element. + * @return {HTMLElement} Parent element. + */ + var getParentElement = function(element) { + return element.parentElement ?? element.getRootNode()?.host ?? null; + }; + /** * Function to find elements based on their text or Aria label. * - * @param {string} text Text (full or partial) - * @param {string} [near] Optional 'near' text - if specified, must have a single match on page + * @param {object} locator Element locator. * @return {HTMLElement} Found elements */ - var findElementsBasedOnText = function(text, near) { + var findElementsBasedOnText = function(locator) { const topContainer = document.querySelector('ion-alert, ion-popover, ion-action-sheet, core-ion-tab.show-tab ion-page.show-page, ion-page.show-page, html'); let container = topContainer; - if (topContainer && near) { - const nearElements = findElementsBasedOnText(near); + if (topContainer && locator.near) { + const nearElements = findElementsBasedOnText(locator.near); if (nearElements.length === 0) { throw new Error('There was no match for near text') @@ -375,19 +386,22 @@ throw new Error('Too many matches for near text'); } - container = nearElementsAncestors[0].parentElement; + container = getParentElement(nearElementsAncestors[0]); } else { - container = nearElements[0].parentElement; + container = getParentElement(nearElements[0]); } } do { - const elements = findElementsBasedOnTextWithin(container, text); + const elements = findElementsBasedOnTextWithin(container, locator.text); + const filteredElements = locator.selector + ? elements.filter(element => element.matches(locator.selector)) + : elements; - if (elements.length > 0) { - return elements; + if (filteredElements.length > 0) { + return filteredElements; } - } while ((container = container.parentElement) && container !== topContainer); + } while ((container = getParentElement(container)) && container !== topContainer); return []; }; @@ -444,10 +458,13 @@ } else { switch (button) { case 'back': - foundButton = findElementsBasedOnText('Back')[0]; + foundButton = findElementsBasedOnText({ text: 'Back' })[0]; break; case 'main menu': - foundButton = findElementsBasedOnText('more', 'Notifications')[0]; + foundButton = findElementsBasedOnText({ + text: 'more', + near: { text: 'Notifications' }, + })[0]; break; default: return 'ERROR: Unsupported standard button type'; @@ -500,15 +517,14 @@ /** * Function to find an arbitrary item based on its text or aria label. * - * @param {string} text Text (full or partial) - * @param {string} [near] Optional 'near' text + * @param {object} locator Element locator. * @return {string} OK if successful, or ERROR: followed by message */ - var behatFind = function(text, near) { - log(`Action - Find ${text}`); + var behatFind = function(locator) { + log('Action - Find', locator); try { - const element = findElementsBasedOnText(text, near)[0]; + const element = findElementsBasedOnText(locator)[0]; if (!element) { return 'ERROR: No matches for text'; @@ -540,15 +556,14 @@ /** * Check whether an item is selected or not. * - * @param {string} text Text (full or partial) - * @param {string} near Optional 'near' text + * @param {object} locator Element locator. * @return {string} YES or NO if successful, or ERROR: followed by message */ - var behatIsSelected = function(text, near) { - log(`Action - Is Selected: "${text}"${near ? ` near "${near}"`: ''}`); + var behatIsSelected = function(locator) { + log('Action - Is Selected', locator); try { - const element = findElementsBasedOnText(text, near)[0]; + const element = findElementsBasedOnText(locator)[0]; return isElementSelected(element, document.body) ? 'YES' : 'NO'; } catch (error) { @@ -559,16 +574,15 @@ /** * Function to press arbitrary item based on its text or Aria label. * - * @param {string} text Text (full or partial) - * @param {string} near Optional 'near' text + * @param {object} locator Element locator. * @return {string} OK if successful, or ERROR: followed by message */ - var behatPress = function(text, near) { - log('Action - Press ' + text + (near === undefined ? '' : ' - near ' + near)); + var behatPress = function(locator) { + log('Action - Press', locator); var found; try { - found = findElementsBasedOnText(text, near)[0]; + found = findElementsBasedOnText(locator)[0]; if (!found) { return 'ERROR: No matches for text'; @@ -697,8 +711,7 @@ return 'ERROR: No matches for text'; } } else { - const elements = findElementsBasedOnText(field); - var found = elements.filter(element => element.matches('input, textarea'))[0]; + found = findElementsBasedOnText({ text: field, selector: 'input, textarea' })[0]; if (!found) { return 'ERROR: No matches for text'; diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 1d995a6ba..7dc3920f6 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -103,18 +103,15 @@ class behat_app extends behat_base { /** * Finds elements in the app. * - * @Then /^I should(?P not)? find "(?P(?:[^"]|\\")*)"(?: near "(?P(?:[^"]|\\")*)")? in the app$/ - * @param string $not - * @param string $text - * @param string $near + * @Then /^I should( not)? find (".+") in the app$/ + * @param bool $not + * @param object $locator */ - public function i_find_in_the_app($not, $text='', $near='') { - $not = !empty($not); - $text = addslashes_js($text); - $near = addslashes_js($near); + public function i_find_in_the_app(bool $not, object $locator) { + $locatorjson = json_encode($locator); - $this->spin(function() use ($not, $text, $near) { - $result = $this->evaluate_script("return window.behat.find(\"$text\", \"$near\");"); + $this->spin(function() use ($not, $locatorjson) { + $result = $this->evaluate_script("return window.behat.find($locatorjson);"); if ($not && $result === 'OK') { throw new DriverException('Error, found an item that should not be found'); @@ -126,22 +123,22 @@ class behat_app extends behat_base { return true; }); + $this->wait_for_pending_js(); } /** * Check if elements are selected in the app. * - * @Then /^"(?P(?:[^"]|\\")*)"(?: near "(?P(?:[^"]|\\")*)")? should(?P not)? be selected in the app$/ - * @param string $text + * @Then /^(".+") should( not)? be selected in the app$/ + * @param object $locator + * @param bool $not */ - public function be_selected_in_the_app($text, $near='', $not='') { - $not = !empty($not); - $text = addslashes_js($text); - $near = addslashes_js($near); + public function be_selected_in_the_app(object $locator, bool $not = false) { + $locatorjson = json_encode($locator); - $this->spin(function() use ($not, $text, $near) { - $result = $this->evaluate_script("return window.behat.isSelected(\"$text\", \"$near\");"); + $this->spin(function() use ($locatorjson, $not) { + $result = $this->evaluate_script("return window.behat.isSelected($locatorjson);"); switch ($result) { case 'YES': @@ -160,6 +157,7 @@ class behat_app extends behat_base { return true; }); + $this->wait_for_pending_js(); } @@ -403,7 +401,7 @@ class behat_app extends behat_base { : $page->find('xpath', '//core-login-site-onboarding'); if ($element) { - $this->i_press_in_the_app('Skip'); + $this->i_press_in_the_app($this->parse_element_locator('"Skip"')); } // Login screen found. @@ -431,7 +429,7 @@ class behat_app extends behat_base { global $CFG; $this->i_set_the_field_in_the_app($this->islegacy ? 'campus.example.edu' : 'Your site', $CFG->wwwroot); - $this->i_press_in_the_app($this->islegacy ? 'Connect!' : 'Connect to your site'); + $this->i_press_in_the_app($this->parse_element_locator($this->islegacy ? '"Connect!"' : '"Connect to your site"')); $this->wait_for_pending_js(); } @@ -448,7 +446,7 @@ class behat_app extends behat_base { // Note there are two 'Log in' texts visible (the title and the button) so we have to use // a 'near' value here. - $this->i_press_in_the_app('Log in', 'Forgotten'); + $this->i_press_in_the_app($this->parse_element_locator('"Log in" near "Forgotten"')); // Wait until the main page appears. $this->spin( @@ -467,18 +465,21 @@ class behat_app extends behat_base { /** * Presses standard buttons in the app. * - * @Given /^I press the (?Pback|main menu|page menu) button in the app$/ + * @Given /^I press the (back|main menu|page menu) button in the app$/ * @param string $button Button type * @throws DriverException If the button push doesn't work */ public function i_press_the_standard_button_in_the_app(string $button) { - $this->spin(function($context, $args) use ($button) { - $result = $this->evaluate_script("return window.behat.pressStandard('{$button}');"); + $this->spin(function() use ($button) { + $result = $this->evaluate_script("return window.behat.pressStandard('$button');"); + if ($result !== 'OK') { throw new DriverException('Error pressing standard button - ' . $result); } + return true; }); + $this->wait_for_pending_js(); } @@ -519,13 +520,16 @@ class behat_app extends behat_base { * @throws DriverException If there isn't a popup to close */ public function i_close_the_popup_in_the_app() { - $this->spin(function($context, $args) { + $this->spin(function() { $result = $this->evaluate_script("return window.behat.closePopup();"); + if ($result !== 'OK') { throw new DriverException('Error closing popup - ' . $result); } + return true; }); + $this->wait_for_pending_js(); } @@ -535,13 +539,24 @@ class behat_app extends behat_base { * Note it is difficult to use the standard 'click on' or 'press' steps because those do not * distinguish visible items and the app always has many non-visible items in the DOM. * - * @Then /^I press "(?P(?:[^"]|\\")*)"(?: near "(?P(?:[^"]|\\")*)")? in the app$/ - * @param string $text Text identifying click target - * @param string $near Text identifying a nearby unique piece of text + * @Then /^I press (".+") in the app$/ + * @param object $locator Element locator * @throws DriverException If the press doesn't work */ - public function i_press_in_the_app($text, $near='') { - $this->press($text, $near); + public function i_press_in_the_app(object $locator) { + $locatorjson = json_encode($locator); + + $this->spin(function() use ($locatorjson) { + $result = $this->evaluate_script("return window.behat.press($locatorjson);"); + + if ($result !== 'OK') { + throw new DriverException('Error pressing item - ' . $result); + } + + return true; + }); + + $this->wait_for_pending_js(); } /** @@ -551,34 +566,32 @@ class behat_app extends behat_base { * with JavaScript, and clicks may not work until they are initialized properly which may cause flaky tests due * to race conditions. * - * @Then /^I (?Punselect|select) "(?P(?:[^"]|\\")*)"(?: near "(?P(?:[^"]|\\")*)")? in the app$/ - * @param string $selectedtext Select/unselect string - * @param string $text Text identifying click target - * @param string $near Text identifying a nearby unique piece of text + * @Then /^I (unselect|select) (".+") in the app$/ + * @param string $selectedtext + * @param object $locator * @throws DriverException If the press doesn't work */ - public function i_select_in_the_app(string $selectedtext, string $text, string $near = '') { + public function i_select_in_the_app(string $selectedtext, object $locator) { $selected = $selectedtext === 'select' ? 'YES' : 'NO'; - $text = addslashes_js($text); - $near = addslashes_js($near); + $locatorjson = json_encode($locator); - $this->spin(function() use ($selectedtext, $selected, $text, $near) { + $this->spin(function() use ($selectedtext, $selected, $locatorjson) { // Don't do anything if the item is already in the expected state. - $result = $this->evaluate_script("return window.behat.isSelected(\"$text\", \"$near\");"); + $result = $this->evaluate_script("return window.behat.isSelected($locatorjson);"); if ($result === $selected) { return true; } // Press item. - $result = $this->evaluate_script("return window.behat.press(\"$text\", \"$near\");"); + $result = $this->evaluate_script("return window.behat.press($locatorjson);"); if ($result !== 'OK') { throw new DriverException('Error pressing item - ' . $result); } // Check that it worked as expected. - $result = $this->evaluate_script("return window.behat.isSelected(\"$text\", \"$near\");"); + $result = $this->evaluate_script("return window.behat.isSelected($locatorjson);"); switch ($result) { case 'YES': @@ -606,54 +619,31 @@ class behat_app extends behat_base { return !is_null($logininput); } - /** - * Clicks on / touches something that is visible in the app, near some other text. - * - * If the $near is specified then when there are multiple matches, it picks the one - * nearest (in DOM terms) $near. $near should be an exact match, or a partial match that only - * has one result. - * - * @param behat_base $base Behat context - * @param string $text Text identifying click target - * @param string $near Text identifying a nearby unique piece of text - * @throws DriverException If the press doesn't work - */ - protected function press(string $text, string $near = '') { - $text = addslashes_js($text); - $near = addslashes_js($near); - - $this->spin(function() use ($text, $near) { - $result = $this->evaluate_script("return window.behat.press(\"$text\", \"$near\");"); - - if ($result !== 'OK') { - throw new DriverException('Error pressing item - ' . $result); - } - - return true; - }); - $this->wait_for_pending_js(); - } - /** * Sets a field to the given text value in the app. * * Currently this only works for input fields which must be identified using a partial or * exact match on the placeholder text. * - * @Given /^I set the field "(?P(?:[^"]|\\")*)" to "(?P(?:[^"]|\\")*)" in the app$/ + * @Given /^I set the field "((?:[^"]|\\")+)" to "((?:[^"]|\\")+)" in the app$/ * @param string $field Text identifying field * @param string $value Value for field * @throws DriverException If the field set doesn't work */ public function i_set_the_field_in_the_app(string $field, string $value) { - $this->spin(function($context, $args) use ($field, $value) { - $result = $this->evaluate_script('return window.behat.setField("' . - addslashes_js($field) . '", "' . addslashes_js($value) . '");'); + $field = addslashes_js($field); + $value = addslashes_js($value); + + $this->spin(function() use ($field, $value) { + $result = $this->evaluate_script("return window.behat.setField(\"$field\", \"$value\");"); + if ($result !== 'OK') { throw new DriverException('Error setting field - ' . $result); } + return true; }); + $this->wait_for_pending_js(); } @@ -662,7 +652,7 @@ class behat_app extends behat_base { * * This can be used to see if the app went to the expected page. * - * @Then /^the header should be "(?P(?:[^"]|\\")*)" in the app$/ + * @Then /^the header should be "((?:[^"]|\\")+)" in the app$/ * @param string $text Expected header text * @throws DriverException If the header can't be retrieved * @throws ExpectationException If the header text is different to the expected value @@ -690,12 +680,10 @@ class behat_app extends behat_base { /** * Check that the app opened a new browser tab. * - * @Given /^the app should(?P not)? have opened a browser tab$/ - * @param string $not + * @Given /^the app should( not)? have opened a browser tab$/ + * @param bool $not */ - public function the_app_should_have_opened_a_browser_tab($not = '') { - $not = !empty($not); - + public function the_app_should_have_opened_a_browser_tab(bool $not) { $this->spin(function() use ($not) { $openedbrowsertab = count($this->getSession()->getWindowNames()) === 2; @@ -748,11 +736,48 @@ class behat_app extends behat_base { /** * Switch navigator online mode. * - * @Given /^I switch offline mode to "(?P(?:[^"]|\\")*)"$/ + * @Given /^I switch offline mode to "(true|false)"$/ * @param string $offline New value for navigator online mode * @throws DriverException If the navigator.online mode is not available */ public function i_switch_offline_mode(string $offline) { - $this->execute_script('appProvider.setForceOffline(' . $offline . ');'); + $this->execute_script("appProvider.setForceOffline($offline);"); } + + /** + * Parse an element locator string. + * + * @Transform /^".+"$/ + * @param string $text Element locator string. + * @return object + */ + public function parse_element_locator($text): object { + preg_match('/^"((?:[^"]|\\")+?)"(?: "([^"]+?)")?(?: near "((?:[^"]|\\")+?)"(?: "([^"]+?)")?)?$/', $text, $matches); + + $locator = [ + 'text' => str_replace('\\"', '"', $matches[1]), + 'selector' => $matches[2] ?? null, + ]; + + if (!empty($matches[3])) { + $locator['near'] = (object) [ + 'text' => str_replace('\\"', '"', $matches[3]), + 'selector' => $matches[4] ?? null, + ]; + } + + return (object) $locator; + } + + /** + * Parse a negation string. + * + * @Transform /^not $/ + * @param string $not Negation string. + * @return bool + */ + public function parse_negation(string $not): bool { + return !empty($not); + } + } From 061ba34e07d9a75e35a24a9a670cccef2333c3fb Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 3 Jun 2021 11:21:50 +0200 Subject: [PATCH 116/220] MOBILE-3320 behat: Update messages tests --- .../tests/behat/app_basic_usage.feature | 318 +++++++++--------- tests/behat/app_behat_runtime.js | 83 +++-- 2 files changed, 221 insertions(+), 180 deletions(-) diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index a2aa8fa3f..8aebbbae3 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_messages @app @app_upto3.9.4 @javascript +@mod @mod_messages @app @javascript Feature: Test basic usage of messages in app In order to participate with messages while using the mobile app As a student @@ -19,23 +19,23 @@ Feature: Test basic usage of messages in app | student1 | C1 | student | | student2 | C1 | student | - @app @3.8.0 Scenario: View recent conversations and contacts When I enter the app And I log in as "teacher1" And I press "Messages" in the app And I press "Contacts" in the app - Then I should see "No contacts" + Then I should find "No contacts" in the app - When I press "addon.messages.search" in the app + When I press "Search people and messages" in the app And I set the field "Search" to "student" in the app - And I press "search" in the app + And I press "Search" "button" in the app And I press "Student1 student1" in the app And I set the field "New message" to "heeey student" in the app And I press "Send" in the app - And I press "Conversation actions menu" in the app + And I press "Display options" in the app And I press "Add to contacts" in the app - And I press "Add" in the app + And I press "Add" near "Are you sure you want to add Student1 student1 to your contacts?" in the app + Then I should find "Contact request sent" in the app When I enter the app And I log in as "student1" @@ -44,86 +44,91 @@ Feature: Test basic usage of messages in app And I press "Requests" in the app And I press "Teacher teacher" in the app And I press "Accept and add to contacts" in the app - And I press the back button in the app - And I press "Contacts" near "Requests" in the app + Then I should not find "Teacher teacher would like to contact you" in the app + + When I press the back button in the app + And I press "Contacts" near "No contact requests" in the app Then the header should be "Contacts" in the app - And I should see "Teacher teacher" + And I should find "Teacher teacher" in the app When I press the back button in the app And I press "Teacher teacher" in the app Then the header should be "Teacher teacher" in the app - And I should see "heeey student" + And I should find "heeey student" in the app - @app @3.8.0 Scenario: Search users When I enter the app And I log in as "student1" And I press "Messages" in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "student2" in the app - And I press "search" in the app - Then I should see "Student2 student2" + And I press "Search" "button" in the app + Then I should find "Student2 student2" in the app When I set the field "Search" to "Teacher" in the app - And I press "search" in the app - Then I should see "Teacher teacher" + And I press "Search" "button" in the app + Then I should find "Teacher teacher" in the app - @app @3.8.0 Scenario: Send/receive messages in existing conversations When I enter the app And I log in as "teacher1" And I press "Messages" in the app And I press "Contacts" in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app - And I press "search" in the app + And I press "Search" "button" in the app And I press "Student1 student1" in the app And I set the field "New message" to "heeey student" in the app And I press "Send" in the app - And I enter the app + Then I should find "heeey student" in the app + + When I enter the app And I log in as "student1" And I press "Messages" in the app And I press "Contacts" in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "teacher" in the app - And I press "search" in the app + And I press "Search" "button" in the app And I press "Teacher teacher" in the app - Then I should see "heeey student" + Then I should find "heeey student" in the app When I set the field "New message" to "hi" in the app And I press "Send" in the app - And I enter the app + Then I should find "hi" in the app + + When I enter the app And I log in as "teacher1" And I press "Messages" in the app - And I press "Contacts" in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app - And I press "search" in the app + And I press "Search" "button" in the app And I press "Student1 student1" in the app - Then I should see "heeey student" - And I should see "hi" - And I set the field "New message" to "byee" in the app - And I press "Send" in the app - Then I should see "heeey student" - And I should see "hi" - And I should see "byee" + Then I should find "heeey student" in the app + And I should find "hi" in the app + + When I set the field "New message" to "byee" in the app + And I press "Send" in the app + Then I should find "heeey student" in the app + And I should find "hi" in the app + And I should find "byee" in the app - @app @3.8.0 Scenario: User profile: send message, add/remove contact When I enter the app And I log in as "teacher1" And I press "Messages" in the app And I press "Contacts" in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "student" in the app - And I press "search" in the app + And I press "Search" "button" in the app And I press "Student1 student1" in the app And I set the field "New message" to "heeey student" in the app And I press "Send" in the app - And I press "Conversation actions menu" in the app + Then I should find "heeey student" in the app + + When I press "Display options" in the app And I press "Add to contacts" in the app And I press "Add" in the app - Then I should see "Contact request sent" + Then I should find "Contact request sent" in the app When I enter the app And I log in as "student1" @@ -131,159 +136,170 @@ Feature: Test basic usage of messages in app And I press "Contacts" in the app And I press "Requests" in the app And I press "Teacher teacher" in the app - Then I should see "Teacher teacher would like to contact you" + Then I should find "Teacher teacher would like to contact you" in the app When I press "Accept and add to contacts" in the app - Then I should not see "Teacher teacher would like to contact you" + Then I should not find "Teacher teacher would like to contact you" in the app - When I press "Teacher teacher" in the app + When I press "Display options" in the app + And I press "User info" in the app And I press "Message" in the app And I set the field "New message" to "hi" in the app - And I press "Send" in the app - Then I should see "heeey student" - And I should see "hi" + And I press "Send" "button" in the app + Then I should find "heeey student" in the app + And I should find "hi" in the app - When I press the back button in the app + When I press "Display options" in the app And I press "Remove from contacts" in the app And I press "Remove" in the app - Then I should see "Add to contacts" + And I wait loading to finish in the app + And I press the back button in the app + And I press the back button in the app + And I press "Display options" in the app + Then I should find "Add to contacts" in the app - When I press the back button in the app - And I press "Conversation actions menu" in the app - Then I should see "Add to contacts" + When I press "Display options" in the app + And I press "Delete conversation" in the app + And I press "Delete" near "Are you sure you would like to delete this entire conversation?" in the app + Then I should not find "heeey student" in the app + And I should not find "hi" in the app - When I press "Delete conversation" in the app - And I press "Delete" in the app - And I should not see "heeey student" - And I should not see "hi" - - @app @3.8.0 Scenario: Send message offline When I enter the app And I log in as "teacher1" And I press "Messages" in the app And I press "Contacts" in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app - And I press "search" in the app + And I press "Search" "button" in the app And I press "Student1 student1" in the app And I switch offline mode to "true" And I set the field "New message" to "heeey student" in the app And I press "Send" in the app - And I set the field "New message" to "byee" in the app + Then I should find "heeey student" in the app + + When I set the field "New message" to "byee" in the app And I press "Send" in the app - And I switch offline mode to "false" + Then I should find "byee" in the app + + When I switch offline mode to "false" And I press the back button in the app And I press "Student1 student1" in the app - And I enter the app + Then I should find "heeey student" in the app + And I should find "byee" in the app + + When I enter the app And I log in as "student1" And I press "Messages" in the app And I press "Teacher teacher" in the app - Then I should see "heeey student" - And I should see "byee" + Then I should find "heeey student" in the app + And I should find "byee" in the app - @app @3.8.0 Scenario: Auto-sync messages When I enter the app And I log in as "teacher1" And I press "Messages" in the app And I press "Contacts" in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app - And I press "search" in the app + And I press "Search" "button" in the app And I press "Student1 student1" in the app And I switch offline mode to "true" And I set the field "New message" to "heeey student" in the app And I press "Send" in the app And I set the field "New message" to "byee" in the app And I press "Send" in the app - And I switch offline mode to "false" + Then I should find "byee" in the app + + When I switch offline mode to "false" And I run cron tasks in the app And I enter the app And I log in as "student1" And I press "Messages" in the app And I press "Teacher teacher" in the app - Then I should see "heeey student" - And I should see "byee" + Then I should find "heeey student" in the app + And I should find "byee" in the app - @app @3.8.0 Scenario: Search for messages When I enter the app And I log in as "teacher1" And I press "Messages" in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app - And I press "search" in the app + And I press "Search" "button" in the app And I press "Student1 student1" in the app And I set the field "New message" to "test message" in the app And I press "Send" in the app - And I set the field "New message" to "search this message" in the app + Then I should find "test message" in the app + + When I set the field "New message" to "search this message" in the app And I press "Send" in the app - And I enter the app + Then I should find "search this message" in the app + + When I enter the app And I log in as "student1" And I press "Messages" in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "search this message" in the app - And I press "search" in the app - Then I should see "Messages" - And I should see "search this message" + And I press "Search" "button" in the app + Then I should find "Messages" in the app + And I should find "search this message" in the app When I press "search this message" near "Teacher teacher" in the app - Then I should see "test message" - And I should see "search this message" + Then I should find "test message" in the app + And I should find "search this message" in the app - @app @3.8.0 Scenario: Star/Unstar When I enter the app And I log in as "teacher1" And I press "Messages" in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app - And I press "search" in the app + And I press "Search" "button" in the app And I press "Student1 student1" in the app And I set the field "New message" to "star message" in the app And I press "Send" in the app - And I enter the app + Then I should find "star message" in the app + + When I enter the app And I log in as "student2" And I press "Messages" in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app - And I press "search" in the app + And I press "Search" "button" in the app And I press "Student1 student1" in the app And I set the field "New message" to "test message student2" in the app And I press "Send" in the app - And I enter the app + Then I should find "test message student2" in the app + + When I enter the app And I log in as "student1" And I press "Messages" in the app - Then I should see "Private (2)" - And I should see "Starred (1)" + Then I should find "Private (2)" in the app + And I should find "Starred (1)" in the app When I press "star message" in the app - And I press "Conversation actions menu" in the app + And I press "Display options" in the app And I press "Star conversation" in the app And I press the back button in the app - Then I should see "Private (1)" - And I should see "Starred (2)" + Then I should find "Private (1)" in the app + And I should find "Starred (2)" in the app When I press "Starred (2)" in the app - Then I should see "Teacher teacher" - And I should see "Student1 student1" + Then I should find "Teacher teacher" in the app + And I should find "Student1 student1" in the app - @app @3.8.0 Scenario: User blocking feature When I enter the app And I log in as "student2" And I press "Course 1" near "Recently accessed courses" in the app And I press "Participants" in the app And I press "Student1 student1" in the app + And I press "Message" in the app + And I press "Display options" in the app And I press "Block user" in the app - And I should see "Are you sure you want to block Student1 student1?" - And I press "Cancel" in the app - And I should see "Block user" - And I press "Block user" in the app - And I press "Block user" near "Cancel" in the app - Then I should see "Unblock user" - But I should not see "Block user" + And I press "Block user" near "Are you sure you want to block Student1 student1?" in the app + Then I should find "You have blocked this user" in the app When I enter the app And I log in as "student1" @@ -291,25 +307,21 @@ Feature: Test basic usage of messages in app And I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app - Then I should see "You are unable to message this user" + Then I should find "You are unable to message this user" in the app When I enter the app And I log in as "student2" And I press "Course 1" near "Recently accessed courses" in the app And I press "Participants" in the app And I press "Student1 student1" in the app - Then I should see "Unblock user" - But I should not see "Block user" + And I press "Message" in the app + And I press "Display options" in the app + Then I should find "Unblock user" in the app + But I should not find "Block user" in the app When I press "Unblock user" in the app - And I press "Cancel" in the app - Then I should see "Unblock user" - But I should not see "Block user" - - When I press "Unblock user" in the app - And I press "Unblock user" near "Cancel" in the app - Then I should see "Block user" - But I should not see "Unblock user" + And I press "Unblock user" near "Are you sure you want to unblock Student1 student1?" in the app + Then I should not find "You have blocked this user" in the app When I enter the app And I log in as "student1" @@ -319,10 +331,9 @@ Feature: Test basic usage of messages in app And I press "Message" in the app And I set the field "New message" to "test message" in the app And I press "Send" in the app - Then I should see "test message" - But I should not see "You are unable to message this user" + Then I should find "test message" in the app + But I should not find "You are unable to message this user" in the app - @app @3.8.0 Scenario: Mute Unmute conversations When I enter the app And I log in as "student1" @@ -332,73 +343,80 @@ Feature: Test basic usage of messages in app And I press "Message" in the app And I set the field "New message" to "test message" in the app And I press "Send" in the app - And I press "Conversation actions menu" in the app + Then I should find "test message" in the app + + When I press "Display options" in the app And I press "Mute" in the app - And I press "Muted conversation" in the app - And I press "Conversation actions menu" in the app - Then I should not see "Mute" + Then I should find "Muted conversation" in the app - When I press "Unmute" in the app - And I press "Conversation actions menu" in the app - Then I should not see "Unmute" + When I press "Display options" in the app + And I press "Unmute" in the app + Then I should not find "Muted conversation" in the app + When I press "Display options" in the app When I press "Mute" in the app - And I press "Messages" in the app + Then I should find "Muted conversation" in the app + + When I press "Messages" in the app And I press "Private (1)" in the app And I press "Student2 student2" in the app - And I press "Conversation actions menu" in the app - Then I should see "Unmute" - But I should not see "Mute" + Then I should find "test message" in the app + And I should find "Muted conversation" in the app - @app @3.8.0 Scenario: Self conversations When I enter the app And I log in as "student1" And I press "Messages" in the app - Then I should see "Starred (1)" + Then I should find "Starred (1)" in the app When I press "Student1 student1" in the app And I set the field "New message" to "self conversation online" in the app And I press "Send" in the app - And I switch offline mode to "true" + Then I should find "self conversation online" in the app + + When I switch offline mode to "true" And I set the field "New message" to "self conversation offline" in the app And I press "Send" in the app - And I switch offline mode to "false" + Then I should find "self conversation offline" in the app + + When I switch offline mode to "false" And I press the back button in the app And I press "Student1 student1" in the app - And I press "Conversation actions menu" in the app - Then I should see "Show delete messages" - And I should see "Delete conversation" + And I press "Display options" in the app + Then I should find "Show delete messages" in the app + And I should find "Delete conversation" in the app When I press "Unstar conversation" in the app - And I press "Conversation actions menu" in the app - Then I should see "Star conversation" - And I should see "Delete conversation" + And I press "Display options" in the app + Then I should find "Star conversation" in the app + And I should find "Delete conversation" in the app When I press "Show delete messages" in the app - Then I should see "self conversation online" - And I should see "self conversation offline" + Then I should find "self conversation online" in the app + And I should find "self conversation offline" in the app When I press "Delete message" near "self conversation offline" in the app And I press "OK" in the app - Then I should see "self conversation online" - But I should not see "self conversation offline" + Then I should find "self conversation online" in the app + But I should not find "self conversation offline" in the app - When I press "Conversation actions menu" in the app + When I press "Display options" in the app And I press "Delete conversation" in the app - And I press "Delete" in the app - Then I should not see "self conversation online" - And I should not see "self conversation offline" + And I press "Delete" near "Are you sure you would like to delete this entire personal conversation?" in the app + Then I should not find "self conversation online" in the app + And I should not find "self conversation offline" in the app When I press the back button in the app - And I press "addon.messages.search" in the app + And I press "Search people and messages" in the app And I set the field "Search" to "Student1 student1" in the app - And I press "search" in the app + And I press "Search" "button" in the app And I press "Student1 student1" in the app And I set the field "New message" to "auto search test" in the app And I press "Send" in the app - And I press the back button in the app + Then I should find "auto search test" in the app + + When I press the back button in the app And I press the back button in the app And I press "Private" in the app And I press "Student1 student1" in the app - Then I should see "auto search test" + Then I should find "auto search test" in the app diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 0f2ee103e..8945cc458 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -406,6 +406,57 @@ return []; }; + /** + * Press an element. + * + * @param {HTMLElement} element Element to press. + */ + var pressElement = function(element) { + if (window.BehatMoodleAppLegacy) { + var mainContent = getNavCtrl().getActive().contentRef().nativeElement; + var rect = element.getBoundingClientRect(); + + // Scroll the item into view. + mainContent.scrollTo(rect.x, rect.y); + + // Simulate a mouse click on the button. + var eventOptions = { + clientX: rect.left + rect.width / 2, + clientY: rect.top + rect.height / 2, + bubbles: true, + view: window, + cancelable: true, + }; + setTimeout(() => element.dispatchEvent(new MouseEvent('mousedown', eventOptions)), 0); + setTimeout(() => element.dispatchEvent(new MouseEvent('mouseup', eventOptions)), 0); + setTimeout(() => element.dispatchEvent(new MouseEvent('click', eventOptions)), 0); + } else { + // Scroll the item into view. + element.scrollIntoView(); + + // Events don't bubble up across Shadow DOM boundaries, and some buttons + // may not work without doing this. + const parentElement = getParentElement(element); + + if (parentElement?.matches('ion-button, ion-back-button')) { + element = parentElement; + } + + // There are some buttons in the app that don't respond to click events, for example + // buttons using the core-supress-events directive. That's why we need to send both + // click and mouse events. + element.dispatchEvent(new MouseEvent('mousedown', eventOptions)); + + setTimeout(() => { + element.dispatchEvent(new MouseEvent('mouseup', eventOptions)); + element.click(); + }, 300); + } + + // Mark busy until the button click finishes processing. + addPendingDelay(); + }; + /** * Function to find and click an app standard button. * @@ -472,10 +523,7 @@ } // Click button - foundButton.click(); - - // Mark busy until the button click finishes processing. - addPendingDelay(); + pressElement(foundButton); return 'OK'; }; @@ -591,32 +639,7 @@ return 'ERROR: ' + error.message; } - if (window.BehatMoodleAppLegacy) { - var mainContent = getNavCtrl().getActive().contentRef().nativeElement; - var rect = found.getBoundingClientRect(); - - // Scroll the item into view. - mainContent.scrollTo(rect.x, rect.y); - - // Simulate a mouse click on the button. - var eventOptions = {clientX: rect.left + rect.width / 2, clientY: rect.top + rect.height / 2, - bubbles: true, view: window, cancelable: true}; - setTimeout(function() { - found.dispatchEvent(new MouseEvent('mousedown', eventOptions)); - }, 0); - setTimeout(function() { - found.dispatchEvent(new MouseEvent('mouseup', eventOptions)); - }, 0); - setTimeout(function() { - found.dispatchEvent(new MouseEvent('click', eventOptions)); - }, 0); - } else { - found.scrollIntoView(); - setTimeout(() => found.click(), 300); - } - - // Mark busy until the button click finishes processing. - addPendingDelay(); + pressElement(found); return 'OK'; }; From 4aa1a534c6c266e16ab6179323265ba0c74fe32c Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 3 Jun 2021 14:45:33 +0200 Subject: [PATCH 117/220] MOBILE-3320 behat: Update course tests --- .../tests/behat/app_basic_usage.feature | 478 +++++++++--------- .../tests/behat/app_course_completion.feature | 20 +- 2 files changed, 247 insertions(+), 251 deletions(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index a74a97831..dac6ccf0f 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_course @app @app_upto3.9.4 @javascript +@mod @mod_course @app @javascript Feature: Test basic usage of one course in app In order to participate in one course while using the mobile app As a student @@ -71,26 +71,25 @@ Feature: Test basic usage of one course in app | activity | name | intro | course | idnumber | groupmode | section | | workshop | Test workshop name | Test workshop | C1 | workshop | 0 | 3 | - @app @3.8.0 Scenario: View course contents When I enter the app And I log in as "student1" And I press "Course 1" near "Recently accessed courses" in the app Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test external name" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" + And I should find "Choice course 1" in the app + And I should find "assignment" in the app + And I should find "Test forum name" in the app + And I should find "Test chat name" in the app + And I should find "Web links" in the app + And I should find "Test external name" in the app + And I should find "Test feedback name" in the app + And I should find "Test glossary" in the app + And I should find "Quiz 1" in the app + And I should find "Test survey name" in the app + And I should find "Test wiki name" in the app + And I should find "Test lesson name" in the app + And I should find "Test scorm name" in the app + And I should find "Test workshop name" in the app When I press "Choice course 1" in the app Then the header should be "Choice course 1" in the app @@ -149,43 +148,42 @@ Feature: Test basic usage of one course in app And I press "Test workshop name" in the app Then the header should be "Test workshop name" in the app - @app @3.8.0 Scenario: View section contents When I enter the app And I log in as "student1" And I press "Course 1" near "Recently accessed courses" in the app Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test external name" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" + And I should find "Choice course 1" in the app + And I should find "assignment" in the app + And I should find "Test forum name" in the app + And I should find "Test chat name" in the app + And I should find "Web links" in the app + And I should find "Test external name" in the app + And I should find "Test feedback name" in the app + And I should find "Test glossary" in the app + And I should find "Quiz 1" in the app + And I should find "Test survey name" in the app + And I should find "Test wiki name" in the app + And I should find "Test lesson name" in the app + And I should find "Test scorm name" in the app + And I should find "Test workshop name" in the app - When I press "arrow dropdown" in the app - And I press "General" near "Sections" in the app - Then I should see "Test forum name" - And I should see "Test wiki name" - But I should not see "Choice course 1" - And I should not see "assignment" - And I should not see "Test chat name" - And I should not see "Web links" - And I should not see "Test external name" - And I should not see "Test feedback name" - And I should not see "Test glossary" - And I should not see "Quiz 1" - And I should not see "Test survey name" - And I should not see "Test lesson name" - And I should not see "Test scorm name" - And I should not see "Test workshop name" + When I press "Section:" in the app + And I press "General" near "Sections" "h2" in the app + Then I should find "Test forum name" in the app + And I should find "Test wiki name" in the app + But I should not find "Choice course 1" in the app + And I should not find "assignment" in the app + And I should not find "Test chat name" in the app + And I should not find "Web links" in the app + And I should not find "Test external name" in the app + And I should not find "Test feedback name" in the app + And I should not find "Test glossary" in the app + And I should not find "Quiz 1" in the app + And I should not find "Test survey name" in the app + And I should not find "Test lesson name" in the app + And I should not find "Test scorm name" in the app + And I should not find "Test workshop name" in the app When I press "Test forum name" in the app Then the header should be "Test forum name" in the app @@ -196,22 +194,22 @@ Feature: Test basic usage of one course in app Then the header should be "Test wiki name" in the app When I press the back button in the app - And I press "arrow dropdown" in the app - And I press "Topic 1" near "Sections" in the app - Then I should see "Choice course 1" - And I should see "assignment" - And I should see "Test external name" - And I should see "Test survey name" - But I should not see "Test forum name" - And I should not see "Test chat name" - And I should not see "Web links" - And I should not see "Test feedback name" - And I should not see "Test glossary" - And I should not see "Quiz 1" - And I should not see "Test wiki name" - And I should not see "Test lesson name" - And I should not see "Test scorm name" - And I should not see "Test workshop name" + And I press "Section:" in the app + And I press "Topic 1" near "Sections" "h2" in the app + Then I should find "Choice course 1" in the app + And I should find "assignment" in the app + And I should find "Test external name" in the app + And I should find "Test survey name" in the app + But I should not find "Test forum name" in the app + And I should not find "Test chat name" in the app + And I should not find "Web links" in the app + And I should not find "Test feedback name" in the app + And I should not find "Test glossary" in the app + And I should not find "Quiz 1" in the app + And I should not find "Test wiki name" in the app + And I should not find "Test lesson name" in the app + And I should not find "Test scorm name" in the app + And I should not find "Test workshop name" in the app When I press "Choice course 1" in the app Then the header should be "Choice course 1" in the app @@ -229,22 +227,22 @@ Feature: Test basic usage of one course in app Then the header should be "Test survey name" in the app When I press the back button in the app - And I press "arrow dropdown" in the app - And I press "Topic 2" near "Sections" in the app - Then I should see "Quiz 1" - And I should see "Test chat name" - And I should see "Test scorm name" - But I should not see "Choice course 1" - And I should not see "assignment" - And I should not see "Test forum name" - And I should not see "Web links" - And I should not see "Test external name" - And I should not see "Test feedback name" - And I should not see "Test glossary" - And I should not see "Test survey name" - And I should not see "Test wiki name" - And I should not see "Test lesson name" - And I should not see "Test workshop name" + And I press "Section:" in the app + And I press "Topic 2" near "Sections" "h2" in the app + Then I should find "Quiz 1" in the app + And I should find "Test chat name" in the app + And I should find "Test scorm name" in the app + But I should not find "Choice course 1" in the app + And I should not find "assignment" in the app + And I should not find "Test forum name" in the app + And I should not find "Web links" in the app + And I should not find "Test external name" in the app + And I should not find "Test feedback name" in the app + And I should not find "Test glossary" in the app + And I should not find "Test survey name" in the app + And I should not find "Test wiki name" in the app + And I should not find "Test lesson name" in the app + And I should not find "Test workshop name" in the app When I press "Test chat name" in the app Then the header should be "Test chat name" in the app @@ -258,22 +256,22 @@ Feature: Test basic usage of one course in app Then the header should be "Test scorm name" in the app When I press the back button in the app - And I press "arrow dropdown" in the app - And I press "Topic 3" near "Sections" in the app - Then I should see "Test feedback name" - And I should see "Test lesson name" - And I should see "Test workshop name" - But I should not see "Choice course 1" - And I should not see "assignment" - And I should not see "Test forum name" - And I should not see "Test chat name" - And I should not see "Web links" - And I should not see "Test external name" - And I should not see "Test glossary" - And I should not see "Quiz 1" - And I should not see "Test survey name" - And I should not see "Test wiki name" - And I should not see "Test scorm name" + And I press "Section:" in the app + And I press "Topic 3" near "Sections" "h2" in the app + Then I should find "Test feedback name" in the app + And I should find "Test lesson name" in the app + And I should find "Test workshop name" in the app + But I should not find "Choice course 1" in the app + And I should not find "assignment" in the app + And I should not find "Test forum name" in the app + And I should not find "Test chat name" in the app + And I should not find "Web links" in the app + And I should not find "Test external name" in the app + And I should not find "Test glossary" in the app + And I should not find "Quiz 1" in the app + And I should not find "Test survey name" in the app + And I should not find "Test wiki name" in the app + And I should not find "Test scorm name" in the app When I press "Test feedback name" in the app And I press "OK" in the app @@ -288,126 +286,126 @@ Feature: Test basic usage of one course in app Then the header should be "Test workshop name" in the app When I press the back button in the app - And I press "arrow dropdown" in the app - And I press "Topic 4" near "Sections" in the app - Then I should see "Web links" - But I should not see "Choice course 1" - And I should not see "assignment" - And I should not see "Test forum name" - And I should not see "Test chat name" - And I should not see "Test external name" - And I should not see "Test feedback name" - And I should not see "Test glossary" - And I should not see "Quiz 1" - And I should not see "Test survey name" - And I should not see "Test wiki name" - And I should not see "Test lesson name" - And I should not see "Test scorm name" - And I should not see "Test workshop name" + And I press "Section:" in the app + And I press "Topic 4" near "Sections" "h2" in the app + Then I should find "Web links" in the app + But I should not find "Choice course 1" in the app + And I should not find "assignment" in the app + And I should not find "Test forum name" in the app + And I should not find "Test chat name" in the app + And I should not find "Test external name" in the app + And I should not find "Test feedback name" in the app + And I should not find "Test glossary" in the app + And I should not find "Quiz 1" in the app + And I should not find "Test survey name" in the app + And I should not find "Test wiki name" in the app + And I should not find "Test lesson name" in the app + And I should not find "Test scorm name" in the app + And I should not find "Test workshop name" in the app When I press "Web links" in the app Then the header should be "Web links" in the app When I press the back button in the app - And I press "arrow dropdown" in the app - And I press "Topic 5" near "Sections" in the app - Then I should see "Test glossary" - But I should not see "Choice course 1" - And I should not see "assignment" - And I should not see "Test forum name" - And I should not see "Test chat name" - And I should not see "Web links" - And I should not see "Test external name" - And I should not see "Test feedback name" - And I should not see "Quiz 1" - And I should not see "Test survey name" - And I should not see "Test wiki name" - And I should not see "Test lesson name" - And I should not see "Test scorm name" - And I should not see "Test workshop name" + And I press "Section:" in the app + And I press "Topic 5" near "Sections" "h2" in the app + Then I should find "Test glossary" in the app + But I should not find "Choice course 1" in the app + And I should not find "assignment" in the app + And I should not find "Test forum name" in the app + And I should not find "Test chat name" in the app + And I should not find "Web links" in the app + And I should not find "Test external name" in the app + And I should not find "Test feedback name" in the app + And I should not find "Quiz 1" in the app + And I should not find "Test survey name" in the app + And I should not find "Test wiki name" in the app + And I should not find "Test lesson name" in the app + And I should not find "Test scorm name" in the app + And I should not find "Test workshop name" in the app When I press "Test glossary" in the app Then the header should be "Test glossary" in the app - @app @3.8.0 Scenario: Navigation between sections using the bottom arrows When I enter the app And I log in as "student1" And I press "Course 1" near "Recently accessed courses" in the app Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test external name" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" + And I should find "Choice course 1" in the app + And I should find "assignment" in the app + And I should find "Test forum name" in the app + And I should find "Test chat name" in the app + And I should find "Web links" in the app + And I should find "Test external name" in the app + And I should find "Test feedback name" in the app + And I should find "Test glossary" in the app + And I should find "Quiz 1" in the app + And I should find "Test survey name" in the app + And I should find "Test wiki name" in the app + And I should find "Test lesson name" in the app + And I should find "Test scorm name" in the app + And I should find "Test workshop name" in the app - When I press "arrow dropdown" in the app - And I press "General" near "Sections" in the app - Then I should see "General" - But I should not see "Topic 1" - And I should not see "Topic 2" - And I should not see "Topic 3" - And I should not see "Topic 4" - And I should not see "Topic 5" + When I press "Section:" in the app + And I press "General" near "Sections" "h2" in the app + Then I should find "General" in the app + And I should find "Next: Topic 1" in the app + But I should not find "Topic 2" in the app + And I should not find "Topic 3" in the app + And I should not find "Topic 4" in the app + And I should not find "Topic 5" in the app + And I should not find "Previous:" in the app - When I press "arrow forward" near "Test wiki name" in the app - Then I should see "Topic 1" - But I should not see "General" - And I should not see "Topic 2" - And I should not see "Topic 3" - And I should not see "Topic 4" - And I should not see "Topic 5" + When I press "Next:" in the app + Then I should find "Topic 1" in the app + And I should find "Previous: General" in the app + And I should find "Next: Topic 2" in the app + But I should not find "Topic 3" in the app + And I should not find "Topic 4" in the app + And I should not find "Topic 5" in the app - When I press "arrow forward" near "Test survey name" in the app - Then I should see "Topic 2" - But I should not see "General" - And I should not see "Topic 1" - And I should not see "Topic 3" - And I should not see "Topic 4" - And I should not see "Topic 5" + When I press "Next:" in the app + Then I should find "Topic 2" in the app + And I should find "Previous: Topic 1" in the app + And I should find "Next: Topic 3" in the app + But I should not find "General" in the app + And I should not find "Topic 4" in the app + And I should not find "Topic 5" in the app - When I press "arrow forward" near "Test scorm name" in the app - Then I should see "Topic 3" - But I should not see "General" - And I should not see "Topic 1" - And I should not see "Topic 2" - And I should not see "Topic 4" - And I should not see "Topic 5" + When I press "Next:" in the app + Then I should find "Topic 3" in the app + And I should find "Previous: Topic 2" in the app + And I should find "Next: Topic 4" in the app + But I should not find "General" in the app + And I should not find "Topic 1" in the app + And I should not find "Topic 5" in the app - When I press "arrow forward" near "Test workshop name" in the app - Then I should see "Topic 4" - But I should not see "General" - And I should not see "Topic 1" - And I should not see "Topic 2" - And I should not see "Topic 3" - And I should not see "Topic 5" + When I press "Next:" in the app + Then I should find "Topic 4" in the app + And I should find "Previous: Topic 3" in the app + And I should find "Next: Topic 5" in the app + But I should not find "General" in the app + And I should not find "Topic 1" in the app + And I should not find "Topic 2" in the app - When I press "arrow forward" near "Web links" in the app - Then I should see "Topic 5" - But I should not see "General" - And I should not see "Topic 1" - And I should not see "Topic 2" - And I should not see "Topic 3" - And I should not see "Topic 4" + When I press "Next:" in the app + Then I should find "Topic 5" in the app + And I should find "Previous: Topic 4" in the app + But I should not find "General" in the app + And I should not find "Topic 1" in the app + And I should not find "Topic 2" in the app + And I should not find "Topic 3" in the app + And I should not find "Next:" in the app - When I press "arrow back" near "Test glossary" in the app - Then I should see "Topic 4" - But I should not see "General" - And I should not see "Topic 1" - And I should not see "Topic 2" - And I should not see "Topic 3" - And I should not see "Topic 5" + When I press "Previous:" in the app + Then I should find "Topic 4" in the app + And I should find "Previous: Topic 3" in the app + And I should find "Next: Topic 5" in the app + But I should not find "General" in the app + And I should not find "Topic 1" in the app + And I should not find "Topic 2" in the app - @app @3.8.0 Scenario: Self enrol Given I enter the app And I log in as "teacher1" @@ -433,22 +431,21 @@ Feature: Test basic usage of one course in app And I wait loading to finish in the app And I press "Contents" in the app Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test external name" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" + And I should find "Choice course 1" in the app + And I should find "assignment" in the app + And I should find "Test forum name" in the app + And I should find "Test chat name" in the app + And I should find "Web links" in the app + And I should find "Test external name" in the app + And I should find "Test feedback name" in the app + And I should find "Test glossary" in the app + And I should find "Quiz 1" in the app + And I should find "Test survey name" in the app + And I should find "Test wiki name" in the app + And I should find "Test lesson name" in the app + And I should find "Test scorm name" in the app + And I should find "Test workshop name" in the app - @app @3.8.0 Scenario: Guest access Given I enter the app And I log in as "teacher1" @@ -469,26 +466,25 @@ Feature: Test basic usage of one course in app And I press "Site home" in the app And I press "Available courses" in the app And I press "Course 1" in the app - Then I should see "Download course" - And I should see "Contents" + Then I should find "Download course" in the app + And I should find "Contents" in the app When I press "Contents" in the app Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" + And I should find "Choice course 1" in the app + And I should find "assignment" in the app + And I should find "Test forum name" in the app + And I should find "Test chat name" in the app + And I should find "Web links" in the app + And I should find "Test feedback name" in the app + And I should find "Test glossary" in the app + And I should find "Quiz 1" in the app + And I should find "Test survey name" in the app + And I should find "Test wiki name" in the app + And I should find "Test lesson name" in the app + And I should find "Test scorm name" in the app + And I should find "Test workshop name" in the app - @app @3.8.0 Scenario: View blocks bellow/beside contents also when All sections selected Given I enter the app And I log in as "teacher1" @@ -515,20 +511,20 @@ Feature: Test basic usage of one course in app And I log in as "student1" And I press "Course 1" near "Recently accessed courses" in the app Then the header should be "Course 1" in the app - And I should see "Choice course 1" - And I should see "assignment" - And I should see "Test forum name" - And I should see "Test chat name" - And I should see "Web links" - And I should see "Test external name" - And I should see "Test feedback name" - And I should see "Test glossary" - And I should see "Quiz 1" - And I should see "Test survey name" - And I should see "Test wiki name" - And I should see "Test lesson name" - And I should see "Test scorm name" - And I should see "Test workshop name" - And I should see "HTML title test" - And I should see "body test" - And I should see "Activities" + And I should find "Choice course 1" in the app + And I should find "assignment" in the app + And I should find "Test forum name" in the app + And I should find "Test chat name" in the app + And I should find "Web links" in the app + And I should find "Test external name" in the app + And I should find "Test feedback name" in the app + And I should find "Test glossary" in the app + And I should find "Quiz 1" in the app + And I should find "Test survey name" in the app + And I should find "Test wiki name" in the app + And I should find "Test lesson name" in the app + And I should find "Test scorm name" in the app + And I should find "Test workshop name" in the app + And I should find "HTML title test" in the app + And I should find "body test" in the app + And I should find "Activities" in the app diff --git a/mod/course/tests/behat/app_course_completion.feature b/mod/course/tests/behat/app_course_completion.feature index 34d482722..c8824dee8 100644 --- a/mod/course/tests/behat/app_course_completion.feature +++ b/mod/course/tests/behat/app_course_completion.feature @@ -1,4 +1,4 @@ -@core @core_course @app @app_upto3.9.4 @javascript +@core @core_course @app @javascript Feature: Check course completion feature. In order to track the progress of the course on mobile device As a student @@ -24,13 +24,13 @@ Feature: Check course completion feature. And I log in as "student1" And I press "Course 1" near "Recently accessed courses" in the app # Set activities as completed. - And I should see "0%" - And I press "Not completed: First forum. Select to mark as complete." in the app - And I should see "50%" - And I press "Not completed: Second forum. Select to mark as complete." in the app - And I should see "100%" + And I should find "0%" in the app + And I press "Mark First forum as done" in the app + And I should find "50%" in the app + And I press "Mark Second forum as done" in the app + And I should find "100%" in the app # Set activities as not completed. - And I press "Completed: First forum. Select to mark as not complete." in the app - And I should see "50%" - And I press "Completed: Second forum. Select to mark as not complete." in the app - And I should see "0%" + And I press "First forum is marked as done. Press to undo." in the app + And I should find "50%" in the app + And I press "Second forum is marked as done. Press to undo." in the app + And I should find "0%" in the app From 6a01f84ed560583d1e9c4eaee715d4f7420b785e Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 7 Jun 2021 10:00:06 +0200 Subject: [PATCH 118/220] MOBILE-3320 behat: Fix negated step --- tests/behat/behat_app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 7dc3920f6..ba732ee74 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -683,7 +683,7 @@ class behat_app extends behat_base { * @Given /^the app should( not)? have opened a browser tab$/ * @param bool $not */ - public function the_app_should_have_opened_a_browser_tab(bool $not) { + public function the_app_should_have_opened_a_browser_tab(bool $not = false) { $this->spin(function() use ($not) { $openedbrowsertab = count($this->getSession()->getWindowNames()) === 2; From 71801580042e3ebe45ddd2ad9c26f4b93283f1a3 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 7 Jun 2021 11:08:46 +0200 Subject: [PATCH 119/220] MOBILE-3320 behat: Update courses tests --- .../tests/behat/app_basic_usage.feature | 72 +++++++++---------- tests/behat/app_behat_runtime.js | 2 +- 2 files changed, 35 insertions(+), 39 deletions(-) diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index e81882cde..d70c3a6ab 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_courses @app @app_upto3.9.4 @javascript +@mod @mod_courses @app @javascript Feature: Test basic usage of courses in app In order to participate in the courses while using the mobile app As a student @@ -34,81 +34,77 @@ Feature: Test basic usage of courses in app | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | | assign | C1 | assign1 | assignment | Test assignment description | 1 | - @app @3.8.0 Scenario: "Dashboard" tab displayed in >= 3.3 sites When I enter the app And I log in as "student1" Then I should see "Dashboard" And the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" + And I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Course 3" in the app When I press "Site home" in the app - Then I should see "Dashboard" + Then I should find "Dashboard" in the app And the header should be "Acceptance test site" in the app When I press "Dashboard" in the app - Then I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" + Then I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Course 3" in the app - @app @3.8.0 Scenario: See my courses When I enter the app And I log in as "student1" Then the header should be "Acceptance test site" in the app - And I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" + And I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Course 3" in the app When I press "Course 1" near "Recently accessed courses" in the app - Then I should see "Choice course 1" + Then I should find "Choice course 1" in the app And the header should be "Course 1" in the app When I press "Choice course 1" in the app - Then I should see "Test choice description" + Then I should find "Test choice description" in the app And the header should be "Choice course 1" in the app When I press the back button in the app And I press the back button in the app And I press "Course 2" near "Recently accessed courses" in the app - Then I should see "Choice course 2" + Then I should find "Choice course 2" in the app And the header should be "Course 2" in the app When I press the back button in the app And I press "Course 3" near "Recently accessed courses" in the app - Then I should see "Choice course 3" + Then I should find "Choice course 3" in the app And the header should be "Course 3" in the app - @app @3.8.0 Scenario: Search for a course When I enter the app And I log in as "student1" And I press "Search courses" in the app And I set the field "Search" to "Course 4" in the app - And I press "Search" in the app - Then I should see "Course 4" + And I press "Search" "button" in the app + Then I should find "Course 4" in the app And the header should be "Search courses" in the app When I press "Course 4" in the app - Then I should see "Course 4" + Then I should find "Course 4" in the app And the header should be "Course 4" in the app When I press the back button in the app And I set the field "Search" to "Course" in the app - And I press "Search" in the app - Then I should see "Course 1" - And I should see "Course 2" - And I should see "Course 3" - And I should see "Course 4" + And I press "Search" "button" in the app + Then I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Course 3" in the app + And I should find "Course 4" in the app - @app @3.8.0 Scenario: Links to actions in Timeline work for teachers/students # Configure assignment as teacher When I enter the app And I log in as "teacher1" - Then I should see "Timeline" + Then I should find "Timeline" in the app Given I press "Course 1" near "Recently accessed courses" in the app And I press "assignment" in the app @@ -129,9 +125,9 @@ Feature: Test basic usage of courses in app And I log in as "student1" And I press "Add submission" in the app Then the header should be "assignment" in the app - And I should see "Test assignment description" - And I should see "No attempt" - And I should see "Due date" + And I should find "Test assignment description" in the app + And I should find "No attempt" in the app + And I should find "Due:" in the app When I press "Add submission" in the app And I set the field "Online text submissions" to "test" in the app @@ -139,18 +135,18 @@ Feature: Test basic usage of courses in app And I press "Submit assignment" in the app And I press "OK" in the app Then the header should be "assignment" in the app - And I should see "Test assignment description" - And I should see "Submitted for grading" - And I should see "Due date" + And I should find "Test assignment description" in the app + And I should find "Submitted for grading" in the app + And I should find "Due:" in the app # Grade assignment as teacher When I enter the app And I log in as "teacher1" And I press "Grade" in the app Then the header should be "assignment" in the app - And I should see "Test assignment description" - And I should see "Time remaining" + And I should find "Test assignment description" in the app + And I should find "Time remaining" in the app When I press "Needs grading" in the app - Then I should see "Student student" - And I should see "Not graded" + Then I should find "Student student" in the app + And I should find "Not graded" in the app diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 8945cc458..960603d82 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -734,7 +734,7 @@ return 'ERROR: No matches for text'; } } else { - found = findElementsBasedOnText({ text: field, selector: 'input, textarea' })[0]; + found = findElementsBasedOnText({ text: field, selector: 'input, textarea, [contenteditable="true"]' })[0]; if (!found) { return 'ERROR: No matches for text'; From c5e89861cac28e11c44bcf7242ec501a97ba5b96 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 7 Jun 2021 17:39:47 +0200 Subject: [PATCH 120/220] MOBILE-3320 behat: Fix change detection in ionic5 --- tests/behat/behat_app.php | 73 +++++++++++++ tests/behat/behat_local_moodlemobileapp.php | 113 -------------------- 2 files changed, 73 insertions(+), 113 deletions(-) delete mode 100644 tests/behat/behat_local_moodlemobileapp.php diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index ba732ee74..a7cb59a8b 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -716,6 +716,66 @@ class behat_app extends behat_base { $this->getSession()->switchToWindow($names[1]); } + /** + * Force cron tasks instead of waiting for the next scheduled execution. + * + * @When /^I run cron tasks in the app$/ + */ + public function i_run_cron_tasks_in_the_app() { + $session = $this->getSession(); + + // Force cron tasks execution and wait until they are completed. + $operationid = random_string(); + + $session->executeScript( + "cronProvider.forceSyncExecution().then(() => { window['behat_{$operationid}_completed'] = true; });" + ); + $this->spin( + function() use ($session, $operationid) { + return $session->evaluateScript("window['behat_{$operationid}_completed'] || false"); + }, + false, + 60, + new ExpectationException('Forced cron tasks in the app took too long to complete', $session) + ); + + // Trigger Angular change detection multiple times in case some changes have + // side-effects that result in further pending operations. + for ($ticks = 5; $ticks > 0; $ticks--) { + $session->executeScript($this->islegacy ? 'appRef.tick();' : 'changeDetector.detectChanges();'); + } + } + + /** + * Wait until loading has finished. + * + * @When /^I wait loading to finish in the app$/ + */ + public function i_wait_loading_to_finish_in_the_app() { + $session = $this->getSession(); + + $this->spin( + function() use ($session) { + $session->executeScript($this->islegacy ? 'appRef.tick();' : 'changeDetector.detectChanges();'); + + $nodes = $this->find_all('css', 'core-loading ion-spinner'); + + foreach ($nodes as $node) { + if (!$node->isVisible()) { + continue; + } + + return false; + } + + return true; + }, + false, + 60, + new ExpectationException('"Loading took too long to complete', $session) + ); + } + /** * Closes the current browser tab. * @@ -780,4 +840,17 @@ class behat_app extends behat_base { return !empty($not); } + /** + * Replaces $WWWROOT for the url of the Moodle site. + * + * @Transform /^(.*\$WWWROOT.*)$/ + * @param string $text Text. + * @return string + */ + public function replace_wwwroot($text) { + global $CFG; + + return str_replace('$WWWROOT', $CFG->behat_wwwroot, $text); + } + } diff --git a/tests/behat/behat_local_moodlemobileapp.php b/tests/behat/behat_local_moodlemobileapp.php deleted file mode 100644 index 1629e0e41..000000000 --- a/tests/behat/behat_local_moodlemobileapp.php +++ /dev/null @@ -1,113 +0,0 @@ -. - -/** - * Behat step definitions. - * - * @package local_apps - * @copyright 2010 Moodle Pty Ltd (http://moodle.com) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -use Behat\Mink\Exception\ExpectationException; - -// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. - -require_once(__DIR__ . '/../../../../lib/behat/behat_base.php'); - -/** - * Behat step definitions. - * - * @package local_apps - * @copyright 2010 Moodle Pty Ltd (http://moodle.com) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class behat_local_moodlemobileapp extends behat_base { - - /** - * Force cron tasks instead of waiting for the next scheduled execution. - * - * @When /^I run cron tasks in the app$/ - */ - public function i_run_cron_tasks_in_the_app() { - $session = $this->getSession(); - - // Force cron tasks execution and wait until they are completed. - $operationid = random_string(); - - $session->executeScript( - "cronProvider.forceSyncExecution().then(() => { window['behat_{$operationid}_completed'] = true; });" - ); - $this->spin( - function() use ($session, $operationid) { - return $session->evaluateScript("window['behat_{$operationid}_completed'] || false"); - }, - false, - 60, - new ExpectationException('Forced cron tasks in the app took too long to complete', $session) - ); - - // Trigger Angular digest cycle multiple times in case some changes have - // side-effects that result in further pending operations. - for ($ticks = 5; $ticks > 0; $ticks--) { - $session->executeScript('appRef.tick();'); - } - } - - /** - * Wait until loading has finished. - * - * @When /^I wait loading to finish in the app$/ - */ - public function i_wait_loading_to_finish_in_the_app() { - $session = $this->getSession(); - - $this->spin( - function() use ($session) { - $session->executeScript('appRef.tick();'); - - $nodes = $this->find_all('css', 'core-loading ion-spinner'); - - foreach ($nodes as $node) { - if (!$node->isVisible()) { - continue; - } - - return false; - } - - return true; - }, - false, - 60, - new ExpectationException('"Loading took too long to complete', $session) - ); - } - - /** - * Replaces $WWWROOT for the url of the Moodle site. - * - * @Transform /^(.*\$WWWROOT.*)$/ - * @param string $text Text. - * @return string - */ - public function arg_replace_wwwroot($text) { - global $CFG; - - return str_replace('$WWWROOT', $CFG->behat_wwwroot, $text); - } - -} From afd7d46b959fac4b60e452fd905e80acf62de546 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 7 Jun 2021 17:40:33 +0200 Subject: [PATCH 121/220] MOBILE-3320 behat: Update forum tests --- mod/forum/tests/behat/app_basic_usage.feature | 210 ++++++++---------- 1 file changed, 91 insertions(+), 119 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 473cbfc21..3fb318d03 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_forum @app @app_upto3.9.4 @javascript +@mod @mod_forum @app @javascript Feature: Test basic usage of forum activity in app In order to participate in the forum while using the mobile app As a student @@ -24,7 +24,6 @@ Feature: Test basic usage of forum activity in app | activity | name | intro | course | idnumber | groupmode | assessed | scale | | forum | Test forum name | Test forum | C1 | forum | 0 | 1 | 1 | - @app @3.8.0 Scenario: Create new discussion When I enter the app And I log in as "student1" @@ -34,12 +33,11 @@ Feature: Test basic usage of forum activity in app And I set the field "Subject" to "My happy subject" in the app And I set the field "Message" to "An awesome message" in the app And I press "Post to forum" in the app - Then I should see "My happy subject" + Then I should find "My happy subject" in the app When I press "My happy subject" in the app - Then I should see "An awesome message" + Then I should find "An awesome message" in the app - @app_from3.7 Scenario: Reply a post When I enter the app And I log in as "student1" @@ -50,15 +48,14 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app And I press "DiscussionSubject" in the app - Then I should see "Reply" + Then I should find "Reply" in the app When I press "Reply" in the app - And I set the field "Write your reply" to "ReplyMessage" in the app + And I set the field "Message" to "ReplyMessage" in the app And I press "Post to forum" in the app - Then I should see "DiscussionMessage" - And I should see "ReplyMessage" + Then I should find "DiscussionMessage" in the app + And I should find "ReplyMessage" in the app - @app @3.8.0 Scenario: Star and pin discussions (student) When I enter the app And I log in as "student1" @@ -73,29 +70,28 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "normal message" in the app And I press "Post to forum" in the app And I press "starred subject" in the app - Then I should see "starred message" + Then I should find "starred message" in the app When I press the back button in the app And I press "Display options" near "starred subject" in the app And I press "Star this discussion" in the app And I press "starred subject" in the app - Then I should see "starred message" + Then I should find "starred message" in the app When I press the back button in the app And I press "normal subject" in the app - Then I should see "normal message" + Then I should find "normal message" in the app When I press the back button in the app And I press "Display options" near "starred subject" in the app And I press "Unstar this discussion" in the app And I press "starred subject" in the app - Then I should see "starred message" + Then I should find "starred message" in the app When I press the back button in the app And I press "normal subject" in the app - Then I should see "normal message" + Then I should find "normal message" in the app - @app @3.8.0 Scenario: Star and pin discussions (teacher) When I enter the app And I log in as "teacher1" @@ -117,35 +113,17 @@ Feature: Test basic usage of forum activity in app And I press "Star this discussion" in the app And I press "Display options" near "Auto-test pin" in the app And I press "Pin this discussion" in the app - Then I should see "Auto-test pin" - And I should see "Auto-test star" - And I should see "Auto-test plain" + Then I should find "Auto-test pin" in the app + And I should find "Auto-test star" in the app + And I should find "Auto-test plain" in the app When I press "Display options" near "Auto-test pin" in the app And I press "Unpin this discussion" in the app And I press "Display options" near "Auto-test star" in the app And I press "Unstar this discussion" in the app - Then I should see "Auto-test star" - And I should see "Auto-test pin" + Then I should find "Auto-test star" in the app + And I should find "Auto-test pin" in the app - @app_upto3.6.0 - Scenario: Star and pin discussions (teacher in 3.6) - When I enter the app - And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app - And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app - And I set the field "Subject" to "Auto-test" in the app - And I set the field "Message" to "Auto-test message" in the app - And I press "Post to forum" in the app - And I press "Auto-test" in the app - Then I should see "Reply" - - When I press "Information" in the app - Then I should not see "Star this discussion" - And I should not see "Pin this discussion" - - @app @3.8.0 Scenario: Edit a not sent reply offline When I enter the app And I log in as "student1" @@ -156,32 +134,31 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app - And I should see "Reply" + And I should find "Reply" in the app When I press the back button in the app And I switch offline mode to "true" And I press "Auto-test" near "Sort by last post creation date in descending order" in the app - Then I should see "Reply" + Then I should find "Reply" in the app When I press "Reply" in the app - And I set the field "Write your reply..." to "not sent reply" in the app + And I set the field "Message" to "not sent reply" in the app And I press "Post to forum" in the app And I press "Display options" near "not sent reply" in the app - Then I should see "Edit" + Then I should find "Edit" in the app When I press "Edit" in the app - And I set the field "Write your reply..." to "not sent reply edited" in the app + And I set the field "Message" to "not sent reply edited" in the app And I press "Post to forum" in the app - Then I should see "Not sent" - And I should see "This Discussion has offline data to be synchronised" + Then I should find "Not sent" in the app + And I should find "This Discussion has offline data to be synchronised" in the app When I switch offline mode to "false" And I press the back button in the app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app - Then I should not see "Not sent" - And I should not see "This Discussion has offline data to be synchronised" + Then I should not find "Not sent" in the app + And I should not find "This Discussion has offline data to be synchronised" in the app - @app @3.8.0 Scenario: Edit a not sent new discussion offline When I enter the app And I log in as "student1" @@ -195,19 +172,18 @@ Feature: Test basic usage of forum activity in app And I press "Auto-test" in the app And I set the field "Message" to "Auto-test message edited" in the app And I press "Post to forum" in the app - Then I should see "This Forum has offline data to be synchronised." + Then I should find "This Forum has offline data to be synchronised." in the app When I switch offline mode to "false" And I press "Auto-test" in the app - Then I should see "Post to forum" + Then I should find "Post to forum" in the app When I press "Post to forum" in the app - Then I should not see "This Forum has offline data to be synchronised." + Then I should not find "This Forum has offline data to be synchronised." in the app When I press "Auto-test" near "Sort by last post creation date in descending order" in the app - And I should see "Auto-test message edited" + And I should find "Auto-test message edited" in the app - @app @3.8.0 Scenario: Edit a forum post (only online) When I enter the app And I log in as "student1" @@ -217,26 +193,25 @@ Feature: Test basic usage of forum activity in app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app - Then I should see "Auto-test" + Then I should find "Auto-test" in the app When I press the back button in the app And I press "Display options" in the app And I press "Show download options" in the app - And I press "cloud download" near "Test forum name" in the app + And I press "Download" near "Test forum name" in the app And I press "Test forum name" in the app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app - Then I should see "Reply" + Then I should find "Reply" in the app When I press "Display options" near "Reply" in the app - Then I should see "Edit" + Then I should find "Edit" in the app When I press "Edit" in the app And I switch offline mode to "true" - And I set the field "Write your reply..." to "Auto-test message edited" in the app + And I set the field "Message" to "Auto-test message edited" in the app And I press "Save changes" in the app - Then I should see "There was a problem connecting to the site. Please check your connection and try again." + Then I should find "There was a problem connecting to the site. Please check your connection and try again." in the app - @app @3.8.0 Scenario: Delete a forum post (only online) When I enter the app And I log in as "student1" @@ -246,32 +221,31 @@ Feature: Test basic usage of forum activity in app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app - Then I should see "Auto-test" + Then I should find "Auto-test" in the app When I press the back button in the app And I press "Display options" in the app And I press "Show download options" in the app - And I press "cloud download" near "Test forum name" in the app + And I press "Download" near "Test forum name" in the app And I press "Test forum name" in the app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app - Then I should see "Reply" + Then I should find "Reply" in the app When I press "Display options" near "Reply" in the app - Then I should see "Delete" + Then I should find "Delete" in the app When I press "Delete" in the app And I press "Cancel" in the app And I switch offline mode to "true" And I press "Display options" near "Reply" in the app - Then I should not see "Delete" + Then I should not find "Delete" in the app When I switch offline mode to "false" And I press "Display options" near "Reply" in the app And I press "Delete" in the app And I press "Delete" in the app - Then I should not see "Auto-test" + Then I should not find "Auto-test" in the app - @app @3.8.0 Scenario: Add/view ratings Given I enter the app And I log in as "student1" @@ -282,50 +256,49 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app And I press "Auto-test" in the app - Then I should see "Reply" + Then I should find "Reply" in the app When I press "Reply" in the app - And I set the field "Write your reply..." to "test2" in the app + And I set the field "Message" to "test2" in the app And I press "Post to forum" in the app When I enter the app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app And I press "Auto-test" in the app - Then I should see "Reply" + Then I should find "Reply" in the app When I press "None" near "Auto-test message" in the app And I press "1" near "Cancel" in the app And I switch offline mode to "true" And I press "None" near "test2" in the app And I press "0" near "Cancel" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "Average of ratings: -" - And I should see "Average of ratings: 1" + Then I should find "Data stored in the device because it couldn't be sent. It will be sent automatically later." in the app + And I should find "Average of ratings: -" in the app + And I should find "Average of ratings: 1" in the app When I switch offline mode to "false" And I press the back button in the app - Then I should see "This Forum has offline data to be synchronised." + Then I should find "This Forum has offline data to be synchronised." in the app When I press "Display options" near "Test forum name" in the app And I press "Synchronise now" in the app - Then I should not see "This Forum has offline data to be synchronised." + Then I should not find "This Forum has offline data to be synchronised." in the app When I press "Auto-test" in the app - Then I should see "Average of ratings: 1" - And I should see "Average of ratings: 0" - But I should not see "Average of ratings: -" + Then I should find "Average of ratings: 1" in the app + And I should find "Average of ratings: 0" in the app + But I should not find "Average of ratings: -" in the app When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Test forum name" in the app And I press "Auto-test" in the app - Then I should see "Average of ratings: 1" - And I should see "Average of ratings: 0" - But I should not see "Average of ratings: -" + Then I should find "Average of ratings: 1" in the app + And I should find "Average of ratings: 0" in the app + But I should not find "Average of ratings: -" in the app - @app @3.8.0 Scenario: Reply a post offline When I enter the app And I log in as "student1" @@ -338,27 +311,26 @@ Feature: Test basic usage of forum activity in app And I press the back button in the app And I press "Display options" in the app And I press "Show download options" in the app - And I press "cloud download" near "Test forum name" in the app + And I press "Download" near "Test forum name" in the app And I press "Test forum name" in the app And I press "DiscussionSubject" in the app And I switch offline mode to "true" - Then I should see "Reply" + Then I should find "Reply" in the app When I press "Reply" in the app - And I set the field "Write your reply" to "ReplyMessage" in the app + And I set the field "Message" to "ReplyMessage" in the app And I press "Post to forum" in the app - Then I should see "DiscussionMessage" - And I should see "ReplyMessage" - And I should see "Not sent" + Then I should find "DiscussionMessage" in the app + And I should find "ReplyMessage" in the app + And I should find "Not sent" in the app When I press the back button in the app And I switch offline mode to "false" And I press "DiscussionSubject" in the app - Then I should see "DiscussionMessage" - And I should see "ReplyMessage" - But I should not see "Not sent" + Then I should find "DiscussionMessage" in the app + And I should find "ReplyMessage" in the app + But I should not find "Not sent" in the app - @app @3.8.0 Scenario: New discussion offline & Sync Forum When I enter the app And I log in as "student1" @@ -369,9 +341,9 @@ Feature: Test basic usage of forum activity in app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app - Then I should see "DiscussionSubject" - And I should see "Not sent" - And I should see "This Forum has offline data to be synchronised." + Then I should find "DiscussionSubject" in the app + And I should find "Not sent" in the app + And I should find "This Forum has offline data to be synchronised." in the app When I switch offline mode to "false" And I press the back button in the app @@ -379,12 +351,11 @@ Feature: Test basic usage of forum activity in app And I press "Display options" near "Test forum name" in the app And I press "Refresh discussions" in the app And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app - Then I should see "DiscussionSubject" - And I should see "DiscussionMessage" - But I should not see "Not sent" - And I should not see "This Forum has offline data to be synchronised." + Then I should find "DiscussionSubject" in the app + And I should find "DiscussionMessage" in the app + But I should not find "Not sent" in the app + And I should not find "This Forum has offline data to be synchronised." in the app - @app @3.8.0 Scenario: New discussion offline & Auto-sync forum When I enter the app And I log in as "student1" @@ -395,22 +366,21 @@ Feature: Test basic usage of forum activity in app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app - Then I should see "DiscussionSubject" - And I should see "Not sent" - And I should see "This Forum has offline data to be synchronised." + Then I should find "DiscussionSubject" in the app + And I should find "Not sent" in the app + And I should find "This Forum has offline data to be synchronised." in the app When I switch offline mode to "false" And I run cron tasks in the app And I wait loading to finish in the app - Then I should not see "Not sent" + Then I should not find "Not sent" in the app When I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app - Then I should see "DiscussionSubject" - And I should see "DiscussionMessage" - But I should not see "Not sent" - And I should not see "This Forum has offline data to be synchronised." + Then I should find "DiscussionSubject" in the app + And I should find "DiscussionMessage" in the app + But I should not find "Not sent" in the app + And I should not find "This Forum has offline data to be synchronised." in the app - @app @3.8.0 Scenario: Prefetch When I enter the app And I log in as "student1" @@ -420,29 +390,31 @@ Feature: Test basic usage of forum activity in app And I set the field "Subject" to "DiscussionSubject 1" in the app And I set the field "Message" to "DiscussionMessage 1" in the app And I press "Post to forum" in the app - Then I should see "DiscussionSubject 1" + Then I should find "DiscussionSubject 1" in the app When I press the back button in the app And I press "Display options" in the app And I press "Show download options" in the app - And I press "cloud download" near "Test forum name" in the app - And I press "Test forum name" in the app + And I press "Download" near "Test forum name" in the app + Then I should find "Downloaded" near "Test forum name" in the app + + When I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "DiscussionSubject 2" in the app And I set the field "Message" to "DiscussionMessage 2" in the app And I press "Post to forum" in the app - Then I should see "DiscussionSubject 1" - And I should see "DiscussionSubject 2" + Then I should find "DiscussionSubject 1" in the app + And I should find "DiscussionSubject 2" in the app When I press the back button in the app And I switch offline mode to "true" And I press "Test forum name" in the app And I press "DiscussionSubject 2" in the app - Then I should see "There was a problem connecting to the site. Please check your connection and try again." + Then I should find "There was a problem connecting to the site. Please check your connection and try again." in the app When I press "OK" in the app And I press the back button in the app And I press "DiscussionSubject 1" in the app - Then I should see "DiscussionSubject 1" - And I should see "DiscussionMessage 1" - But I should not see "There was a problem connecting to the site. Please check your connection and try again." + Then I should find "DiscussionSubject 1" in the app + And I should find "DiscussionMessage 1" in the app + But I should not find "There was a problem connecting to the site. Please check your connection and try again." in the app From 3d3dc9c7b1fa33d583e6543aabd23de5a8df5649 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 8 Jun 2021 17:53:04 +0200 Subject: [PATCH 122/220] MOBILE-3320 behat: Update login tests --- mod/login/tests/behat/app_basic_usage.feature | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index fc0f78236..e3b5c3bab 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_login @app @app_upto3.9.4 @javascript +@mod @mod_login @app @javascript Feature: Test basic usage of login in app I need basic login functionality to work @@ -17,50 +17,48 @@ Feature: Test basic usage of login in app | student2 | C1 | student | | teacher1 | C1 | editingteacher | - @app @3.8.0 Scenario: Add a new site in the app & Site name in displayed when adding a new site When I enter the app And I press the back button in the app - And I set the field "https://campus.example.edu" to "$WWWROOT" in the app + And I set the field "Your site" to "$WWWROOT" in the app And I press "Connect to your site" in the app - Then I should see "Acceptance test site" + Then I should find "Acceptance test site" in the app When I set the field "Username" to "student1" in the app And I set the field "Password" to "student1" in the app And I press "Log in" near "Forgotten your username or password?" in the app - Then I should see "Acceptance test site" - But I should not see "Log in" + Then I should find "Acceptance test site" in the app + But I should not find "Log in" in the app - @app @3.8.0 Scenario: Add a non existing site When I enter the app And I log in as "student1" - And I press "menu" in the app + And I press the main menu button in the app And I press "Change site" in the app - And I press "add" in the app - And I set the field "https://campus.example.edu" to "Wrong Site Address" in the app + And I press "Add" in the app + And I set the field "Your site" to "Wrong Site Address" in the app And I press enter in the app - Then I should see "Cannot connect" - And I should see "Please check the address is correct." + Then I should find "Cannot connect" in the app + And I should find "Please check the address is correct." in the app - @app @3.8.0 Scenario: Delete a site When I enter the app And I log in as "student1" - And I press "menu" in the app + And I press the main menu button in the app And I press "Change site" in the app - Then I should see "Acceptance test site" + Then I should find "Acceptance test site" in the app And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" in the app - Then I should see "Connect to Moodle" - But I should not see "Acceptance test site" + And I press "Delete" near "Acceptance test site" in the app + And I press "Delete" near "Are you sure you want to delete the site Acceptance test site?" in the app + Then I should find "Connect to Moodle" in the app + But I should not find "Acceptance test site" in the app - @app @3.8.0 Scenario: Require minium version of the app for a site + + # Log in with a previous required version When I enter the app And I log in as "teacher1" - And I press "menu" in the app + And I press the main menu button in the app And I press "Website" in the app And I switch to the browser tab opened by the app And I follow "Log in" @@ -72,8 +70,11 @@ Feature: Test basic usage of login in app And I press "Save changes" And I close the browser tab opened by the app And I enter the app - And I log in as "teacher1" - And I press "menu" in the app + Then I should not find "App update required" in the app + + # Log in with a future required version + When I log in as "teacher1" + And I press the main menu button in the app And I press "Website" in the app And I switch to the browser tab opened by the app And I follow "Log in" @@ -85,4 +86,4 @@ Feature: Test basic usage of login in app And I press "Save changes" And I close the browser tab opened by the app And I enter the app - Then I should see "App update required" + Then I should find "App update required" in the app From 9e3ba9dbdfaa9c1019eb3cb93c1556d5c3e11591 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 8 Jun 2021 18:36:17 +0200 Subject: [PATCH 123/220] MOBILE-3320 behat: Update assignment tests --- .../tests/behat/app_basic_usage.feature | 76 +++++++++---------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index 778cfe1ec..ecd892b82 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_assign @app @app_upto3.9.4 @javascript +@mod @mod_assign @app @javascript Feature: Test basic usage of assignment activity in app In order to participate in the assignment while using the mobile app I need basic assignment functionality to work @@ -19,7 +19,6 @@ Feature: Test basic usage of assignment activity in app | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | duedate | attemptreopenmethod | | assign | C1 | assign1 | assignment1 | Test assignment description1 | 1 | 1029844800 | manual | - @app @3.8.0 Scenario: View assign description, due date & View list of student submissions (as teacher) & View own submission or student submission # Create, edit and submit as a student When I enter the app @@ -27,27 +26,27 @@ Feature: Test basic usage of assignment activity in app And I press "Course 1" near "Recently accessed courses" in the app And I press "assignment1" in the app Then the header should be "assignment1" in the app - And I should see "Test assignment description1" - And I should see "Due date" - And I should see "Tuesday, 20 August 2002, 12:00 PM" + And I should find "Test assignment description1" in the app + And I should find "Due:" in the app + And I should find "20 August 2002, 12:00 PM" in the app When I press "Add submission" in the app And I set the field "Online text submissions" to "Submission test" in the app And I press "Save" in the app - Then I should see "Draft (not submitted)" - And I should see "Not graded" + Then I should find "Draft (not submitted)" in the app + And I should find "Not graded" in the app When I press "Edit submission" in the app And I set the field "Online text submissions" to "Submission test edited" in the app And I press "Save" in the app And I press "OK" in the app - Then I should see "Submission test edited" + Then I should find "Submission test edited" in the app When I press "Submit assignment" in the app And I press "OK" in the app - Then I should see "Submitted for grading" - And I should see "Not graded" - And I should see "Submission test edited" + Then I should find "Submitted for grading" in the app + And I should find "Not graded" in the app + And I should find "Submission test edited" in the app # View as a teacher When I enter the app @@ -57,14 +56,13 @@ Feature: Test basic usage of assignment activity in app Then the header should be "assignment1" in the app When I press "Submitted" in the app - Then I should see "Student student" - And I should see "Not graded" + Then I should find "Student student" in the app + And I should find "Not graded" in the app When I press "Student student" near "assignment1" in the app - Then I should see "Online text submissions" - And I should see "Submission test edited" + Then I should find "Online text submissions" in the app + And I should find "Submission test edited" in the app - @app @3.8.0 Scenario: Edit/Add submission (online text) & Add new attempt from previous submission & Submit for grading # Submit first attempt as a student Given I enter the app @@ -86,23 +84,23 @@ Feature: Test basic usage of assignment activity in app And I press "Student student" near "assignment1" in the app And I press "Grade" in the app And I press "Allow another attempt" in the app - And I press "Done" - Then I should see "Reopened" - And I should see "Not graded" + And I press "Done" in the app + Then I should find "Reopened" in the app + And I should find "Not graded" in the app # Submit second attempt as a student When I enter the app And I log in as "student1" And I press "Course 1" near "Recently accessed courses" in the app And I press "assignment1" in the app - Then I should see "Reopened" - And I should see "2 out of Unlimited" - And I should see "Add a new attempt based on previous submission" - And I should see "Add a new attempt" + Then I should find "Reopened" in the app + And I should find "2 out of Unlimited" in the app + And I should find "Add a new attempt based on previous submission" in the app + And I should find "Add a new attempt" in the app When I press "Add a new attempt based on previous submission" in the app And I press "OK" in the app - Then I should see "Submission test 1st attempt" + Then I should find "Submission test 1st attempt" in the app When I set the field "Online text submissions" to "Submission test 2nd attempt" in the app And I press "Save" in the app @@ -117,10 +115,9 @@ Feature: Test basic usage of assignment activity in app And I press "assignment1" in the app And I press "Participants" in the app And I press "Student student" near "assignment1" in the app - Then I should see "Online text submissions" - And I should see "Submission test 2nd attempt" + Then I should find "Online text submissions" in the app + And I should find "Submission test 2nd attempt" in the app - @app @3.8.0 Scenario: Add submission offline (online text) & Submit for grading offline & Sync submissions When I enter the app And I log in as "student1" @@ -132,17 +129,16 @@ Feature: Test basic usage of assignment activity in app And I press "Save" in the app And I press "Submit assignment" in the app And I press "OK" in the app - Then I should see "This Assignment has offline data to be synchronised." + Then I should find "This Assignment has offline data to be synchronised." in the app When I switch offline mode to "false" And I press the back button in the app And I press "assignment1" in the app And I press "Display options" in the app And I press "Refresh" in the app - Then I should see "Submitted for grading" - But I should not see "This Assignment has offline data to be synchronised." + Then I should find "Submitted for grading" in the app + But I should not find "This Assignment has offline data to be synchronised." in the app - @app @3.8.0 Scenario: Edit an offline submission before synchronising it When I enter the app And I log in as "student1" @@ -152,23 +148,23 @@ Feature: Test basic usage of assignment activity in app And I switch offline mode to "true" And I set the field "Online text submissions" to "Submission test original offline" in the app And I press "Save" in the app - Then I should see "This Assignment has offline data to be synchronised." - And I should see "Submission test original offline" + Then I should find "This Assignment has offline data to be synchronised." in the app + And I should find "Submission test original offline" in the app When I press "Edit submission" in the app And I set the field "Online text submissions" to "Submission test edited offline" in the app And I press "Save" in the app - Then I should see "This Assignment has offline data to be synchronised." - And I should see "Submission test edited offline" - But I should not see "Submission test original offline" + Then I should find "This Assignment has offline data to be synchronised." in the app + And I should find "Submission test edited offline" in the app + But I should not find "Submission test original offline" in the app When I press "Submit assignment" in the app And I press "OK" in the app - Then I should see "This Assignment has offline data to be synchronised." + Then I should find "This Assignment has offline data to be synchronised." in the app When I switch offline mode to "false" And I press the back button in the app And I press "assignment1" in the app - Then I should see "Submitted for grading" - And I should see "Submission test edited offline" - But I should not see "This Assignment has offline data to be synchronised." + Then I should find "Submitted for grading" in the app + And I should find "Submission test edited offline" in the app + But I should not find "This Assignment has offline data to be synchronised." in the app From 708df84f6609996e6febc0fd57f10482be8116d0 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 9 Jun 2021 10:21:02 +0200 Subject: [PATCH 124/220] MOBILE-3320 behat: Update quiz tests --- mod/quiz/tests/behat/app_basic_usage.feature | 96 ++++++++++--------- .../tests/behat/app_quiz_navigation.feature | 83 +++++----------- tests/behat/behat_app.php | 2 +- 3 files changed, 73 insertions(+), 108 deletions(-) diff --git a/mod/quiz/tests/behat/app_basic_usage.feature b/mod/quiz/tests/behat/app_basic_usage.feature index 7b2f92086..d03e3c9db 100755 --- a/mod/quiz/tests/behat/app_basic_usage.feature +++ b/mod/quiz/tests/behat/app_basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_quiz @app @app_upto3.9.4 @javascript +@mod @mod_quiz @app @javascript Feature: Attempt a quiz in app As a student In order to demonstrate what I know @@ -42,7 +42,7 @@ Feature: Attempt a quiz in app | Test questions | shortanswer | TF4 | Text of the second question | | Test questions | numerical | TF5 | Text of the third question | | Test questions | essay | TF6 | Text of the fourth question | - | Test questions | ddwtos | TF7 | Text of the fifth question | + | Test questions | ddwtos | TF7 | The [[1]] brown [[2]] jumped over the [[3]] dog. | | Test questions | truefalse | TF8 | Text of the sixth question | | Test questions | match | TF9 | Text of the seventh question | And quiz "Quiz 2" contains the following questions: @@ -55,60 +55,58 @@ Feature: Attempt a quiz in app | TF8 | 6 | | TF9 | 7 | - @app @3.8.0 Scenario: View a quiz entry page (attempts, status, etc.) When I enter the app And I log in as "student1" And I press "Course 1" near "Course overview" in the app And I press "Quiz 1" in the app And I press "Attempt quiz now" in the app - Then I should see "Text of the first question" - But I should not see "Text of the second question" + Then I should find "Text of the first question" in the app + But I should not find "Text of the second question" in the app When I press "Next" near "Question 1" in the app - Then I should see "Text of the second question" - But I should not see "Text of the first question" + Then I should find "Text of the second question" in the app + But I should not find "Text of the first question" in the app When I press "Previous" near "Question 2" in the app - Then I should see "Text of the first question" - But I should not see "Text of the second question" + Then I should find "Text of the first question" in the app + But I should not find "Text of the second question" in the app When I press "Next" near "Quiz 1" in the app - Then I should see "Text of the second question" - But I should not see "Text of the first question" + Then I should find "Text of the second question" in the app + But I should not find "Text of the first question" in the app When I press "Previous" near "Quiz 1" in the app - Then I should see "Text of the first question" - But I should not see "Text of the second question" + Then I should find "Text of the first question" in the app + But I should not find "Text of the second question" in the app When I press "Next" near "Question 1" in the app And I press "Next" near "Quiz 1" in the app - Then I should see "Summary of attempt" + Then I should find "Summary of attempt" in the app When I press "Return to attempt" in the app - Then I should see "Text of the second question" - But I should not see "Text of the first question" + Then I should find "Text of the second question" in the app + But I should not find "Text of the first question" in the app When I press "Next" in the app And I press "Submit all and finish" in the app - Then I should see "Once you submit" + Then I should find "Once you submit" in the app When I press "Cancel" near "Once you submit" in the app - Then I should see "Summary of attempt" + Then I should find "Summary of attempt" in the app When I press "Submit all and finish" in the app And I press "OK" near "Once you submit" in the app - Then I should see "Review of attempt 1" - And I should see "Started on" - And I should see "State" - And I should see "Completed on" - And I should see "Time taken" - And I should see "Marks" - And I should see "Grade" - And I should see "Question 1" - And I should see "Question 2" + Then I should find "Review of attempt 1" in the app + And I should find "Started on" in the app + And I should find "State" in the app + And I should find "Completed on" in the app + And I should find "Time taken" in the app + And I should find "Marks" in the app + And I should find "Grade" in the app + And I should find "Question 1" in the app + And I should find "Question 2" in the app - @app @3.8.0 Scenario: Attempt a quiz (all question types) When I enter the app And I log in as "student1" @@ -117,31 +115,37 @@ Feature: Attempt a quiz in app And I press "Attempt quiz now" in the app And I press "Four" in the app And I press "Three" in the app - And I press "Next" near "Question 1" in the app + And I press "Next" "ion-button" near "Quiz 2" in the app And I set the field "Answer" to "testing" in the app - And I press "Next" near "Question 2" in the app + And I press "Next" "ion-button" near "Question 2" in the app And I set the field "Answer" to "5" in the app - And I press "Next" near "Question 3" in the app + And I press "Next" "ion-button" near "Question 3" in the app And I set the field "Answer" to "Testing an essay" in the app - And I press "Next" near "Question 4" in the app - And I press "lazy" in the app - And I press "Next" near "Question 5" in the app + And I press "Next" "ion-button" near "Question 4" in the app + And I press "quick" ".drag" in the app + And I press "" ".place1.drop" in the app + And I press "fox" ".drag" in the app + And I press "" ".place2.drop" in the app + And I press "lazy" ".drag" in the app + And I press "" ".place3.drop" in the app + And I press "Next" "ion-button" near "Question 5" in the app And I press "True" in the app - And I press "Next" near "Question 6" in the app - And I press "Choose..." near "frog" in the app + And I press "Next" "ion-button" near "Question 6" in the app + And I press "Choose... , frog" in the app And I press "amphibian" in the app - And I press "Choose..." near "newt" in the app + And I press "Choose... , newt" in the app And I press "insect" in the app - And I press "Choose..." near "cat" in the app + And I press "Choose... , cat" in the app And I press "mammal" in the app - And I press "Next" near "Question 7" in the app - And I press "Submit all and finish" in the app - And I press "OK" in the app - Then I should see "Review of attempt 1" - And I should see "Finished" - And I should see "Not yet graded" + And I press "Next" "ion-button" near "Question 7" in the app + Then I should not find "Not yet answered" in the app + + When I press "Submit all and finish" in the app + And I press "OK" in the app + Then I should find "Review of attempt 1" in the app + And I should find "Finished" in the app + And I should find "Not yet graded" in the app - @app @3.8.0 Scenario: Submit a quiz & Review a quiz attempt When I enter the app And I log in as "student1" @@ -154,7 +158,7 @@ Feature: Attempt a quiz in app And I press "Next" near "Question 2" in the app And I press "Submit all and finish" in the app And I press "OK" in the app - Then I should see "Review of attempt 1" + Then I should find "Review of attempt 1" in the app When I enter the app And I log in as "teacher1" diff --git a/mod/quiz/tests/behat/app_quiz_navigation.feature b/mod/quiz/tests/behat/app_quiz_navigation.feature index 75b8b7a9d..cf8a69dd4 100644 --- a/mod/quiz/tests/behat/app_quiz_navigation.feature +++ b/mod/quiz/tests/behat/app_quiz_navigation.feature @@ -1,4 +1,4 @@ -@mod @mod_quiz @app @app_upto3.9.4 @javascript +@mod @mod_quiz @app @javascript Feature: Attempt a quiz in app As a student In order to demonstrate what I know @@ -29,81 +29,42 @@ Feature: Attempt a quiz in app | TF1 | 1 | | TF2 | 2 | - @app_upto3.7.0 - Scenario: Next and previous navigation in the 3.6 app + Scenario: Next and previous navigation Given I enter the app And I log in as "student1" When I press "Course 1" near "Course overview" in the app And I press "Quiz 1" in the app And I press "Attempt quiz now" in the app - Then I should see "Text of the first question" - And I should not see "Text of the second question" + Then I should find "Text of the first question" in the app + And I should not find "Text of the second question" in the app And I press "Next" near "Question 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" + And I should find "Text of the second question" in the app + And I should not find "Text of the first question" in the app And I press "Previous" near "Question 2" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" + And I should not find "Text of the second question" in the app + And I should find "Text of the first question" in the app And I press "Next" near "Quiz 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" + And I should find "Text of the second question" in the app + And I should not find "Text of the first question" in the app And I press "Previous" near "Quiz 1" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" + And I should not find "Text of the second question" in the app + And I should find "Text of the first question" in the app And I press "Next" near "Question 1" in the app And I press "Next" near "Quiz 1" in the app - And I should see "Summary of attempt" + And I should find "Summary of attempt" in the app And I press "Return to attempt" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" + And I should find "Text of the second question" in the app + And I should not find "Text of the first question" in the app And I press "Next" in the app And I press "Submit all and finish" in the app - And I should see "Once you submit" + And I should find "Once you submit" in the app And I press "Cancel" near "Once you submit" in the app - And I should see "Summary of attempt" + And I should find "Summary of attempt" in the app And I press "Submit all and finish" in the app And I press "OK" near "Once you submit" in the app - And I should see "Review" - And I press "home" in the app - And I should see "Acceptance test site" - - @app_from3.7.1 - Scenario: Next and previous navigation in the 3.7 app - Given I enter the app - And I log in as "student1" - When I press "Course 1" near "Course overview" in the app - And I press "Quiz 1" in the app - And I press "Attempt quiz now" in the app - Then I should see "Text of the first question" - And I should not see "Text of the second question" - And I press "Next" near "Question 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Previous" near "Question 2" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" - And I press "Next" near "Quiz 1" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Previous" near "Quiz 1" in the app - And I should not see "Text of the second question" - And I should see "Text of the first question" - And I press "Next" near "Question 1" in the app - And I press "Next" near "Quiz 1" in the app - And I should see "Summary of attempt" - And I press "Return to attempt" in the app - And I should see "Text of the second question" - And I should not see "Text of the first question" - And I press "Next" in the app - And I press "Submit all and finish" in the app - And I should see "Once you submit" - And I press "Cancel" near "Once you submit" in the app - And I should see "Summary of attempt" - And I press "Submit all and finish" in the app - And I press "OK" near "Once you submit" in the app - And I should see "Review" - And I press "home" in the app - And I should see "Are you sure" - And I should see "OK" + And I should find "Review" in the app + And I press "Home" in the app + And I should find "Are you sure" in the app + And I should find "OK" in the app And I press "OK" in the app - And I should see "Acceptance test site" + And I should find "Acceptance test site" in the app diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index a7cb59a8b..f74f8c888 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -812,7 +812,7 @@ class behat_app extends behat_base { * @return object */ public function parse_element_locator($text): object { - preg_match('/^"((?:[^"]|\\")+?)"(?: "([^"]+?)")?(?: near "((?:[^"]|\\")+?)"(?: "([^"]+?)")?)?$/', $text, $matches); + preg_match('/^"((?:[^"]|\\")*?)"(?: "([^"]*?)")?(?: near "((?:[^"]|\\")*?)"(?: "([^"]*?)")?)?$/', $text, $matches); $locator = [ 'text' => str_replace('\\"', '"', $matches[1]), From 6d1b7c52ed4ff866f6ee0140b9567381e715d407 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Jun 2021 15:14:51 +0200 Subject: [PATCH 125/220] MOBILE-3320 behat: Add navigation tests --- mod/messages/tests/behat/navigation.feature | 42 +++++++++++++++++++ tests/behat/behat_app.php | 23 ++++++++-- ...s.feature => navigation_deeplinks.feature} | 31 +++++++++++--- 3 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 mod/messages/tests/behat/navigation.feature rename tests/behat/{navigation_pushnotifications.feature => navigation_deeplinks.feature} (58%) diff --git a/mod/messages/tests/behat/navigation.feature b/mod/messages/tests/behat/navigation.feature new file mode 100644 index 000000000..15bded770 --- /dev/null +++ b/mod/messages/tests/behat/navigation.feature @@ -0,0 +1,42 @@ +@mod @mod_messages @app @javascript +Feature: Test messages navigation in the app + + Background: + Given the following "users" exist: + | username | firstname | + | teacher | Teacher | + | student | Student | + And the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | teacher | C1 | editingteacher | + | student | C1 | student | + + Scenario: Avoid recursive links to profile + When I enter the app + And I log in as "teacher" + And I press "Messages" in the app + And I press "Contacts" in the app + And I press "Search people and messages" in the app + And I set the field "Search" to "student" in the app + And I press "Search" "button" in the app + And I press "Student" in the app + And I set the field "New message" to "Hi there" in the app + And I press "Send" in the app + Then I should find "Hi there" in the app + + When I press "Display options" in the app + And I press "User info" in the app + Then I should find "Details" in the app + + When I press "Message" in the app + Then I should find "Hi there" in the app + + When I press "Display options" in the app + Then I should not find "User info" in the app + + When I press the back button in the app + And I press the back button in the app + Then I should find "Hi there" in the app diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index f74f8c888..081f43fba 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -484,12 +484,12 @@ class behat_app extends behat_base { } /** - * Receives push notifications for forum events. + * Receives push notifications. * - * @Given /^I receive a forum push notification for:$/ + * @Given /^I receive a push notification in the app for:$/ * @param TableNode $data */ - public function i_receive_a_forum_push_notification(TableNode $data) { + public function i_receive_a_push_notification(TableNode $data) { global $DB, $CFG; $data = (object) $data->getColumnsHash()[0]; @@ -513,6 +513,23 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } + /** + * Opens a custom link. + * + * @Given /^I open a custom link in the app for:$/ + */ + public function i_open_a_custom_link(TableNode $data) { + global $DB, $CFG; + + $data = (object) $data->getColumnsHash()[0]; + $discussion = $DB->get_record('forum_discussions', ['name' => $data->discussion]); + $pageurl = "{$CFG->behat_wwwroot}/mod/forum/discuss.php?d={$discussion->id}"; + $url = "moodlemobile://link=" . urlencode($pageurl); + + $this->evaluate_script("return window.urlSchemes.handleCustomURL('$url')"); + $this->wait_for_pending_js(); + } + /** * Closes a popup by clicking on the 'backdrop' behind it. * diff --git a/tests/behat/navigation_pushnotifications.feature b/tests/behat/navigation_deeplinks.feature similarity index 58% rename from tests/behat/navigation_pushnotifications.feature rename to tests/behat/navigation_deeplinks.feature index d36002e0c..051ae52fc 100644 --- a/tests/behat/navigation_pushnotifications.feature +++ b/tests/behat/navigation_deeplinks.feature @@ -1,5 +1,5 @@ @app @javascript -Feature: It navigates properly after receiving push notifications. +Feature: It navigates properly using deep links. Background: Given the following "users" exist: @@ -22,7 +22,7 @@ Feature: It navigates properly after receiving push notifications. And the following config values are set as admin: | forcelogout | 1 | tool_mobile | - Scenario: Open a forum push notification + Scenario: Receive a push notification When I enter the app And I log in as "student2" And I press the main menu button in the app @@ -31,12 +31,33 @@ Feature: It navigates properly after receiving push notifications. And I set the field "Your site" to "$WWWROOT" in the app And I press "Connect to your site" in the app And I log in as "student1" - And I receive a forum push notification for: - | username | course | module | discussion | - | student2 | C1 | forum | Forum topic | + And I receive a push notification in the app for: + | username | module | discussion | + | student2 | forum | Forum topic | Then I should find "Reconnect" in the app When I set the field "Password" to "student2" in the app And I press "Log in" in the app Then I should find "Forum topic" in the app And I should find "Forum message" in the app + But I should not find "Site home" in the app + + When I press the back button in the app + Then I should find "Site home" in the app + But I should not find "Forum topic" in the app + And I should not find "Forum message" in the app + + Scenario: Open a link with a custom URL + When I launch the app + And I open a custom link in the app for: + | discussion | + | Forum topic | + And I log in as "student1" + Then I should find "Forum topic" in the app + And I should find "Forum message" in the app + But I should not find "Site home" in the app + + When I press the back button in the app + Then I should find "Site home" in the app + But I should not find "Forum topic" in the app + And I should not find "Forum message" in the app From 561206b7854fad711b75ee35d296cf489da5b29d Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Jun 2021 15:15:38 +0200 Subject: [PATCH 126/220] MOBILE-3320 behat: Implement step to wait restart --- tests/behat/behat_app.php | 95 +++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 38 deletions(-) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 081f43fba..ca2e742fa 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -100,6 +100,19 @@ class behat_app extends behat_base { $this->prepare_browser(); } + /** + * @Then /^I wait the app to restart$/ + */ + public function i_wait_the_app_to_restart() { + // Wait window to reload. + $this->spin(function() { + return $this->evaluate_script("return !window.behat;"); + }); + + // Prepare testing runtime again. + $this->prepare_browser(false); + } + /** * Finds elements in the app. * @@ -347,24 +360,28 @@ class behat_app extends behat_base { * @param string $url App URL * @throws DriverException If the app fails to load properly */ - protected function prepare_browser() { - // Restart the browser and set its size. - $this->getSession()->restart(); - $this->resize_window('360x720', true); + protected function prepare_browser(bool $restart = true) { + if ($restart) { + // Restart the browser and set its size. + $this->getSession()->restart(); + $this->resize_window('360x720', true); - if (empty($this->ionicurl)) { - $this->ionicurl = $this->start_or_reuse_ionic(); + if (empty($this->ionicurl)) { + $this->ionicurl = $this->start_or_reuse_ionic(); + } + + // Check whether the app is running a legacy version. + $json = @file_get_contents("{$this->ionicurl}/assets/env.json") ?: @file_get_contents("{$this->ionicurl}/config.json"); + $data = json_decode($json); + $appversion = $data->build->version ?? str_replace('-dev', '', $data->versionname); + + $this->islegacy = version_compare($appversion, '3.9.5', '<'); + + // Visit the Ionic URL. + $this->getSession()->visit($this->ionicurl); } - // Check whether the app is running a legacy version. - $json = @file_get_contents("{$this->ionicurl}/assets/env.json") ?: @file_get_contents("{$this->ionicurl}/config.json"); - $data = json_decode($json); - $appversion = $data->build->version ?? str_replace('-dev', '', $data->versionname); - - $this->islegacy = version_compare($appversion, '3.9.5', '<'); - - // Visit the Ionic URL and wait for it to load. - $this->getSession()->visit($this->ionicurl); + // Wait the application to load. $this->spin(function($context) { $title = $context->getSession()->getPage()->find('xpath', '//title'); @@ -387,34 +404,36 @@ class behat_app extends behat_base { $this->execute_script("window.BehatMoodleAppLegacy = $islegacyboolean;"); $this->execute_script(file_get_contents(__DIR__ . '/app_behat_runtime.js')); - // Assert initial page. - $this->spin(function($context) { - $page = $context->getSession()->getPage(); - $element = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); - - if ($element) { - // Wait for the onboarding modal to open, if any. - $this->wait_for_pending_js(); - - $element = $this->islegacy - ? $page->find('xpath', '//page-core-login-site-onboarding') - : $page->find('xpath', '//core-login-site-onboarding'); + if ($restart) { + // Assert initial page. + $this->spin(function($context) { + $page = $context->getSession()->getPage(); + $element = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); if ($element) { - $this->i_press_in_the_app($this->parse_element_locator('"Skip"')); + // Wait for the onboarding modal to open, if any. + $this->wait_for_pending_js(); + + $element = $this->islegacy + ? $page->find('xpath', '//page-core-login-site-onboarding') + : $page->find('xpath', '//core-login-site-onboarding'); + + if ($element) { + $this->i_press_in_the_app($this->parse_element_locator('"Skip"')); + } + + // Login screen found. + return true; } - // Login screen found. - return true; - } + if ($page->find('xpath', '//page-core-mainmenu')) { + // Main menu found. + return true; + } - if ($page->find('xpath', '//page-core-mainmenu')) { - // Main menu found. - return true; - } - - throw new DriverException('Moodle app not launched properly'); - }, false, 60); + throw new DriverException('Moodle app not launched properly'); + }, false, 60); + } // Continue only after JS finishes. $this->wait_for_pending_js(); From dd7db580e7a0db69db590169dc049573909cc7f6 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 15 Jun 2021 18:32:31 +0200 Subject: [PATCH 127/220] MOBILE-3320 behat: Test activity deep links --- tests/behat/behat_app.php | 45 +++++++++++++++++++++++ tests/behat/navigation_activities.feature | 32 ++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 tests/behat/navigation_activities.feature diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index ca2e742fa..966af9496 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -532,6 +532,24 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } + /** + * Replace arguments from the content in the given activity field. + * + * @Given /^I replace the arguments in "([^"]+)" "([^"]+)"$/ + */ + public function i_replace_arguments_in_the_activity(string $idnumber, string $field) { + global $DB; + + $coursemodule = $DB->get_record('course_modules', compact('idnumber')); + $module = $DB->get_record('modules', ['id' => $coursemodule->module]); + $activity = $DB->get_record($module->name, ['id' => $coursemodule->instance]); + + $DB->update_record($module->name, [ + 'id' => $coursemodule->instance, + $field => $this->replace_arguments($activity->{$field}), + ]); + } + /** * Opens a custom link. * @@ -889,4 +907,31 @@ class behat_app extends behat_base { return str_replace('$WWWROOT', $CFG->behat_wwwroot, $text); } + /** + * Replace arguments with the format "${activity:field}" from a string, where "activity" is + * the idnumber of an activity and "field" is the activity's field to get replacement from. + * + * At the moment, the only field supported is "cmid", the id of the course module for this activity. + * + * @param string $text Original text. + * @return string Text with arguments replaced. + */ + protected function replace_arguments(string $text): string { + global $DB; + + preg_match_all("/\\$\\{([^:}]+):([^}]+)\\}/", $text, $matches); + + foreach ($matches[0] as $index => $match) { + switch ($matches[2][$index]) { + case 'cmid': + $coursemodule = $DB->get_record('course_modules', ['idnumber' => $matches[1][$index]]); + $text = str_replace($match, $coursemodule->id, $text); + + break; + } + } + + return $text; + } + } diff --git a/tests/behat/navigation_activities.feature b/tests/behat/navigation_activities.feature new file mode 100644 index 000000000..210b8293e --- /dev/null +++ b/tests/behat/navigation_activities.feature @@ -0,0 +1,32 @@ +@app @javascript +Feature: It navigates properly within activities. + + Background: + Given the following "users" exist: + | username | + | student | + And the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | student | C1 | student | + And the following "activities" exist: + | activity | idnumber | course | name | intro | content | + | label | label | C1 | Label | Label description | - | + | page | page | C1 | Page | - | Go to label | + And I replace the arguments in "page" "content" + + Scenario: Navigates using deep links + When I enter the app + And I log in as "student" + And I press "Course 1" in the app + And I press "Page" in the app + And I press "Go to label" in the app + Then I should find "Label description" in the app + + When I press the back button in the app + Then I should find "Go to label" in the app + + When I press the back button in the app + Then I should find "Label description" in the app From d614cf426d72ff40d39cc0385b68444739e62ae6 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 21 Jun 2021 10:36:26 +0200 Subject: [PATCH 128/220] MOBILE-3320 behat: Trigger change detection once Doing it multiple times seems to cause some internal race conditions in Angular that result in flaky tests --- tests/behat/behat_app.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 966af9496..69126df33 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -793,11 +793,8 @@ class behat_app extends behat_base { new ExpectationException('Forced cron tasks in the app took too long to complete', $session) ); - // Trigger Angular change detection multiple times in case some changes have - // side-effects that result in further pending operations. - for ($ticks = 5; $ticks > 0; $ticks--) { - $session->executeScript($this->islegacy ? 'appRef.tick();' : 'changeDetector.detectChanges();'); - } + // Trigger Angular change detection + $session->executeScript($this->islegacy ? 'appRef.tick();' : 'changeDetector.detectChanges();'); } /** From d02da246b5582643d5fcc0eebc3c65ef4adb9146 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 6 Jul 2021 18:59:54 +0200 Subject: [PATCH 129/220] MOBILE-3320 behat: Remove modern JS --- tests/behat/app_behat_runtime.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 960603d82..40a71cdf7 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -296,7 +296,8 @@ } const labelledBy = currentNode.getAttribute('aria-labelledby'); - if (labelledBy && container.querySelector(`#${labelledBy}`)?.innerText?.includes(text)) { + const labelElement = labelledBy && container.querySelector(`#${labelledBy}`); + if (labelElement && labelElement.innerText && labelElement.innerText.includes(text)) { elements.push(currentNode); continue; @@ -361,7 +362,7 @@ * @return {HTMLElement} Parent element. */ var getParentElement = function(element) { - return element.parentElement ?? element.getRootNode()?.host ?? null; + return element.parentElement || (element.getRootNode() && element.getRootNode().host) || null; }; /** @@ -438,7 +439,7 @@ // may not work without doing this. const parentElement = getParentElement(element); - if (parentElement?.matches('ion-button, ion-back-button')) { + if (parentElement && parentElement.matches('ion-button, ion-back-button')) { element = parentElement; } From dce0d45d6e9e8f0fa557396b06a256a940501c42 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 19 Jul 2021 09:56:02 +0200 Subject: [PATCH 130/220] MOBILE-3320 course: Fix behat using LMS master --- mod/course/tests/behat/app_basic_usage.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index dac6ccf0f..59a69c6b3 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -498,6 +498,7 @@ Feature: Test basic usage of one course in app And I click on "Side panel" "button" And I follow "Add a block" And I follow "HTML" + And I click on "[aria-label=\"Close drawer\"]" "css_element" And I click on "Side panel" "button" And I follow "Add a block" And I follow "Activities" From bd16e812875a93f4fb302252462641819d57c4c8 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 1 Sep 2021 12:55:49 +0200 Subject: [PATCH 131/220] MOBILE-3833 behat: Fix tests with master --- .../tests/behat/app_basic_usage.feature | 4 +-- mod/login/tests/behat/app_basic_usage.feature | 31 +++---------------- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 59a69c6b3..e252e7943 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -485,7 +485,7 @@ Feature: Test basic usage of one course in app And I should find "Test scorm name" in the app And I should find "Test workshop name" in the app - Scenario: View blocks bellow/beside contents also when All sections selected + Scenario: View blocks below/beside contents also when All sections selected Given I enter the app And I log in as "teacher1" And I press "Course 1" near "Recently accessed courses" in the app @@ -498,7 +498,7 @@ Feature: Test basic usage of one course in app And I click on "Side panel" "button" And I follow "Add a block" And I follow "HTML" - And I click on "[aria-label=\"Close drawer\"]" "css_element" + And I click on "#theme_boost-drawers-blocks [aria-label=\"Close drawer\"]" "css_element" And I click on "Side panel" "button" And I follow "Add a block" And I follow "Activities" diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index e3b5c3bab..0685c75c2 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -56,34 +56,13 @@ Feature: Test basic usage of login in app Scenario: Require minium version of the app for a site # Log in with a previous required version + Given the following config values are set as admin: + | minimumversion | 3.8.1 | tool_mobile | When I enter the app - And I log in as "teacher1" - And I press the main menu button in the app - And I press "Website" in the app - And I switch to the browser tab opened by the app - And I follow "Log in" - And I log in as "admin" - And I press "Side panel" - And I follow "Site administration" - And I follow "Mobile authentication" - And I set the field "Minimum app version required" to "3.8.1" - And I press "Save changes" - And I close the browser tab opened by the app - And I enter the app Then I should not find "App update required" in the app # Log in with a future required version - When I log in as "teacher1" - And I press the main menu button in the app - And I press "Website" in the app - And I switch to the browser tab opened by the app - And I follow "Log in" - And I log in as "admin" - And I press "Side panel" - And I follow "Site administration" - And I follow "Mobile authentication" - And I set the field "Minimum app version required" to "11.0.0" - And I press "Save changes" - And I close the browser tab opened by the app - And I enter the app + Given the following config values are set as admin: + | minimumversion | 11.0.0 | tool_mobile | + When I enter the app Then I should find "App update required" in the app From 0c55a9b0b0eeaed656fb040899b8e4566c79399f Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Mon, 6 Sep 2021 11:05:10 +0200 Subject: [PATCH 132/220] MOBILE-3793 behat: Fix forum edit offline test --- mod/forum/tests/behat/app_basic_usage.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 3fb318d03..b2cb3d8ac 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -149,7 +149,7 @@ Feature: Test basic usage of forum activity in app When I press "Edit" in the app And I set the field "Message" to "not sent reply edited" in the app - And I press "Post to forum" in the app + And I press "Save changes" in the app Then I should find "Not sent" in the app And I should find "This Discussion has offline data to be synchronised" in the app From b79dbd2ddad3c03a8f51522b73d2cbd48a768a1b Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 22 Sep 2021 14:10:59 +0200 Subject: [PATCH 133/220] MDL-72116 behat: Fix tests using removed blocks --- .../tests/behat/app_basic_usage.feature | 16 ++++++------ .../tests/behat/app_basic_usage.feature | 24 ++++++++--------- .../tests/behat/app_basic_usage.feature | 14 +++++----- .../tests/behat/app_course_completion.feature | 2 +- .../tests/behat/app_basic_usage.feature | 8 +++--- .../tests/behat/app_basic_usage.feature | 26 +++++++++---------- .../tests/behat/app_basic_usage.feature | 10 +++---- 7 files changed, 50 insertions(+), 50 deletions(-) diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index ecd892b82..722ef7cec 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -23,7 +23,7 @@ Feature: Test basic usage of assignment activity in app # Create, edit and submit as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "assignment1" in the app Then the header should be "assignment1" in the app And I should find "Test assignment description1" in the app @@ -51,7 +51,7 @@ Feature: Test basic usage of assignment activity in app # View as a teacher When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "assignment1" in the app Then the header should be "assignment1" in the app @@ -67,7 +67,7 @@ Feature: Test basic usage of assignment activity in app # Submit first attempt as a student Given I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "assignment1" in the app And I press "Add submission" in the app And I set the field "Online text submissions" to "Submission test 1st attempt" in the app @@ -78,7 +78,7 @@ Feature: Test basic usage of assignment activity in app # Allow more attempts as a teacher When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "assignment1" in the app And I press "Participants" in the app And I press "Student student" near "assignment1" in the app @@ -91,7 +91,7 @@ Feature: Test basic usage of assignment activity in app # Submit second attempt as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "assignment1" in the app Then I should find "Reopened" in the app And I should find "2 out of Unlimited" in the app @@ -111,7 +111,7 @@ Feature: Test basic usage of assignment activity in app # View second attempt as a teacher When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "assignment1" in the app And I press "Participants" in the app And I press "Student student" near "assignment1" in the app @@ -121,7 +121,7 @@ Feature: Test basic usage of assignment activity in app Scenario: Add submission offline (online text) & Submit for grading offline & Sync submissions When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "assignment1" in the app And I press "Add submission" in the app And I switch offline mode to "true" @@ -142,7 +142,7 @@ Feature: Test basic usage of assignment activity in app Scenario: Edit an offline submission before synchronising it When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "assignment1" in the app And I press "Add submission" in the app And I switch offline mode to "true" diff --git a/mod/comments/tests/behat/app_basic_usage.feature b/mod/comments/tests/behat/app_basic_usage.feature index 2bc874f98..b8036aa17 100755 --- a/mod/comments/tests/behat/app_basic_usage.feature +++ b/mod/comments/tests/behat/app_basic_usage.feature @@ -28,7 +28,7 @@ Feature: Test basic usage of comments in app # Create database entry and comment as a teacher Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Data" in the app And I press "Display options" in the app And I press "Open in browser" in the app @@ -41,7 +41,7 @@ Feature: Test basic usage of comments in app And I close the browser tab opened by the app When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Data" in the app And I press "add" in the app And I set the field "Test field name" to "Test" in the app @@ -60,7 +60,7 @@ Feature: Test basic usage of comments in app # Create and delete comments as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Data" in the app And I press "More" in the app And I press "Comments (1)" in the app @@ -87,7 +87,7 @@ Feature: Test basic usage of comments in app Scenario: Add comments offline & Delete comments offline & Sync comments (database) Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Data" in the app And I press "Display options" in the app And I press "Open in browser" in the app @@ -100,7 +100,7 @@ Feature: Test basic usage of comments in app And I close the browser tab opened by the app When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Data" in the app And I press "add" in the app And I set the field "Test field name" to "Test" in the app @@ -150,7 +150,7 @@ Feature: Test basic usage of comments in app # Create glossary entry and comment as a teacher When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -169,7 +169,7 @@ Feature: Test basic usage of comments in app # Create and delete comments as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "potato" in the app And I press "Comments (1)" in the app @@ -196,7 +196,7 @@ Feature: Test basic usage of comments in app Scenario: Add comments offline & Delete comments offline & Sync comments (glossary) When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -247,7 +247,7 @@ Feature: Test basic usage of comments in app # Create blog as a teacher Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "menu" in the app And I press "Website" in the app And I switch to the browser tab opened by the app @@ -268,7 +268,7 @@ Feature: Test basic usage of comments in app # Create and delete comments as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "menu" in the app And I press "Site blog" in the app Then I should see "Blog test" @@ -297,7 +297,7 @@ Feature: Test basic usage of comments in app # Create blog as a teacher Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "menu" in the app And I press "Website" in the app And I switch to the browser tab opened by the app @@ -318,7 +318,7 @@ Feature: Test basic usage of comments in app # Create and delete comments as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "menu" in the app And I press "Site blog" in the app Then I should see "Blog test" diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index e252e7943..249543aa4 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -74,7 +74,7 @@ Feature: Test basic usage of one course in app Scenario: View course contents When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -151,7 +151,7 @@ Feature: Test basic usage of one course in app Scenario: View section contents When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -330,7 +330,7 @@ Feature: Test basic usage of one course in app Scenario: Navigation between sections using the bottom arrows When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -409,7 +409,7 @@ Feature: Test basic usage of one course in app Scenario: Self enrol Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app @@ -449,7 +449,7 @@ Feature: Test basic usage of one course in app Scenario: Guest access Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app @@ -488,7 +488,7 @@ Feature: Test basic usage of one course in app Scenario: View blocks below/beside contents also when All sections selected Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app @@ -510,7 +510,7 @@ Feature: Test basic usage of one course in app And I close the browser tab opened by the app When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app diff --git a/mod/course/tests/behat/app_course_completion.feature b/mod/course/tests/behat/app_course_completion.feature index c8824dee8..129f56c79 100644 --- a/mod/course/tests/behat/app_course_completion.feature +++ b/mod/course/tests/behat/app_course_completion.feature @@ -22,7 +22,7 @@ Feature: Check course completion feature. | forum | Second forum | C1 | forum2 | 1 | 0 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app # Set activities as completed. And I should find "0%" in the app And I press "Mark First forum as done" in the app diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index d70c3a6ab..1f931143e 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -60,7 +60,7 @@ Feature: Test basic usage of courses in app And I should find "Course 2" in the app And I should find "Course 3" in the app - When I press "Course 1" near "Recently accessed courses" in the app + When I press "Course 1" near "Course overview" in the app Then I should find "Choice course 1" in the app And the header should be "Course 1" in the app @@ -70,12 +70,12 @@ Feature: Test basic usage of courses in app When I press the back button in the app And I press the back button in the app - And I press "Course 2" near "Recently accessed courses" in the app + And I press "Course 2" near "Course overview" in the app Then I should find "Choice course 2" in the app And the header should be "Course 2" in the app When I press the back button in the app - And I press "Course 3" near "Recently accessed courses" in the app + And I press "Course 3" near "Course overview" in the app Then I should find "Choice course 3" in the app And the header should be "Course 3" in the app @@ -106,7 +106,7 @@ Feature: Test basic usage of courses in app And I log in as "teacher1" Then I should find "Timeline" in the app - Given I press "Course 1" near "Recently accessed courses" in the app + Given I press "Course 1" near "Course overview" in the app And I press "assignment" in the app And I press "Display options" in the app And I press "Open in browser" in the app diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index db323a308..169345a26 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -29,7 +29,7 @@ Feature: Test basic usage of glossary in app Scenario: View a glossary and its terms When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -56,7 +56,7 @@ Feature: Test basic usage of glossary in app Scenario: Change filters (include search) When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -94,7 +94,7 @@ Feature: Test basic usage of glossary in app When the "glossary" filter is "on" And I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -139,7 +139,7 @@ Feature: Test basic usage of glossary in app # Create entries as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -164,7 +164,7 @@ Feature: Test basic usage of glossary in app # Write comments as a teacher When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then I should see "Comments (0)" @@ -186,7 +186,7 @@ Feature: Test basic usage of glossary in app # View comments as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then I should see "Comments (2)" @@ -199,7 +199,7 @@ Feature: Test basic usage of glossary in app Scenario: Prefetch When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -222,7 +222,7 @@ Feature: Test basic usage of glossary in app And I press "Download" in the app And I press the back button in the app And I press the back button in the app - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I switch offline mode to "true" And I press "Test glossary" in the app Then the header should be "Test glossary" in the app @@ -240,7 +240,7 @@ Feature: Test basic usage of glossary in app Scenario: Sync When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I switch offline mode to "true" And I press "close" in the app @@ -282,7 +282,7 @@ Feature: Test basic usage of glossary in app # Create entries as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -304,7 +304,7 @@ Feature: Test basic usage of glossary in app # Rate entries as teacher1 When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then I should see "Average of ratings: -" @@ -316,7 +316,7 @@ Feature: Test basic usage of glossary in app # Rate entries as teacher2 When I enter the app And I log in as "teacher2" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "mountain" in the app And I switch offline mode to "true" @@ -337,7 +337,7 @@ Feature: Test basic usage of glossary in app # View ratings as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then the header should be "mountain" in the app diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index 8aebbbae3..a03944489 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -292,7 +292,7 @@ Feature: Test basic usage of messages in app Scenario: User blocking feature When I enter the app And I log in as "student2" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Participants" in the app And I press "Student1 student1" in the app And I press "Message" in the app @@ -303,7 +303,7 @@ Feature: Test basic usage of messages in app When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app @@ -311,7 +311,7 @@ Feature: Test basic usage of messages in app When I enter the app And I log in as "student2" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Participants" in the app And I press "Student1 student1" in the app And I press "Message" in the app @@ -325,7 +325,7 @@ Feature: Test basic usage of messages in app When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app @@ -337,7 +337,7 @@ Feature: Test basic usage of messages in app Scenario: Mute Unmute conversations When I enter the app And I log in as "student1" - And I press "Course 1" near "Recently accessed courses" in the app + And I press "Course 1" near "Course overview" in the app And I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app From a51cf30b2f30d6653b13bf4fd94b30c7e23c3256 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 22 Sep 2021 14:11:56 +0200 Subject: [PATCH 134/220] MOBILE-3860 behat: Update error message --- mod/login/tests/behat/app_basic_usage.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index 0685c75c2..6709d8c76 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -39,7 +39,7 @@ Feature: Test basic usage of login in app And I set the field "Your site" to "Wrong Site Address" in the app And I press enter in the app Then I should find "Cannot connect" in the app - And I should find "Please check the address is correct." in the app + And I should find "Wrong Site Address" in the app Scenario: Delete a site When I enter the app From 423281a960100f7249278d6bd8c3803a1f404e82 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 22 Sep 2021 14:14:15 +0200 Subject: [PATCH 135/220] MOBILE-3833 behat: Fix UI changes in LMS --- mod/choice/tests/behat/app_basic_usage.feature | 3 ++- mod/course/tests/behat/app_basic_usage.feature | 7 ++++--- mod/courses/tests/behat/app_basic_usage.feature | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 6f0caea8e..98819e5d2 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -174,6 +174,7 @@ Feature: Test basic usage of choice activity in app And I should find "Option 3: 0" in the app But I should not find "This Choice has offline data to be synchronised." in the app + # TODO remove LMS UI steps in app tests Scenario: Download students choice in text format # Submit answer as student Given the following "activities" exist: @@ -199,6 +200,6 @@ Feature: Test basic usage of choice activity in app And I switch to the browser tab opened by the app And I log in as "teacher1" And I press "Actions menu" - And I follow "View 1 responses" + And I follow "Responses" And I press "Download in text format" # TODO Then I should find "..." in the downloads folder diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 249543aa4..de031bb6b 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -485,6 +485,7 @@ Feature: Test basic usage of one course in app And I should find "Test scorm name" in the app And I should find "Test workshop name" in the app + # TODO remove LMS UI steps in app tests Scenario: View blocks below/beside contents also when All sections selected Given I enter the app And I log in as "teacher1" @@ -497,14 +498,14 @@ Feature: Test basic usage of one course in app And I press "Turn editing on" And I click on "Side panel" "button" And I follow "Add a block" - And I follow "HTML" + And I follow "Text" And I click on "#theme_boost-drawers-blocks [aria-label=\"Close drawer\"]" "css_element" And I click on "Side panel" "button" And I follow "Add a block" And I follow "Activities" And I click on "Actions menu" "icon" in the "#action-menu-toggle-0" "css_element" - And I follow "Configure (new HTML block) block" - And I set the field "HTML block title" to "HTML title test" + And I follow "Configure (new text block) block" + And I set the field "Text block title" to "HTML title test" And I set the field "Content" to "body test" And I press "Save changes" And I close the browser tab opened by the app diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index 1f931143e..d0a6e3dc7 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -100,6 +100,7 @@ Feature: Test basic usage of courses in app And I should find "Course 3" in the app And I should find "Course 4" in the app + # TODO remove LMS UI steps in app tests Scenario: Links to actions in Timeline work for teachers/students # Configure assignment as teacher When I enter the app @@ -113,7 +114,7 @@ Feature: Test basic usage of courses in app And I switch to the browser tab opened by the app And I log in as "teacher1" And I press "Actions menu" - And I follow "Edit settings" + And I follow "Settings" And I press "Expand all" And I click on "duedate[enabled]" "checkbox" And I click on "gradingduedate[enabled]" "checkbox" From 23f2fdd7e2f366692029ea7a5dda9438e5e54cbb Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 23 Sep 2021 12:26:49 +0200 Subject: [PATCH 136/220] MOBILE-3875 behat: Support launching app runtime Without skipping onboarding or waiting the app to become interactive. --- tests/behat/behat_app.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 69126df33..088961a64 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -85,19 +85,19 @@ class behat_app extends behat_base { /** * Opens the Moodle app in the browser. * - * @Given /^I launch the app$/ + * @Given /^I launch the app( runtime)?$/ * @throws DriverException Issue with configuration or feature file * @throws dml_exception Problem with Moodle setup * @throws ExpectationException Problem with resizing window */ - public function i_launch_the_app() { + public function i_launch_the_app(string $runtime = '') { // Check the app tag was set. if (!$this->has_tag('app')) { throw new DriverException('Requires @app tag on scenario or feature.'); } // Go to page and prepare browser for app. - $this->prepare_browser(); + $this->prepare_browser(['skiponboarding' => empty($runtime)]); } /** @@ -110,7 +110,7 @@ class behat_app extends behat_base { }); // Prepare testing runtime again. - $this->prepare_browser(false); + $this->prepare_browser(['restart' => false]); } /** @@ -360,7 +360,10 @@ class behat_app extends behat_base { * @param string $url App URL * @throws DriverException If the app fails to load properly */ - protected function prepare_browser(bool $restart = true) { + protected function prepare_browser(array $options = []) { + $restart = $options['restart'] ?? true; + $skiponboarding = $options['skiponboarding'] ?? true; + if ($restart) { // Restart the browser and set its size. $this->getSession()->restart(); @@ -406,11 +409,15 @@ class behat_app extends behat_base { if ($restart) { // Assert initial page. - $this->spin(function($context) { + $this->spin(function($context) use ($skiponboarding) { $page = $context->getSession()->getPage(); $element = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); if ($element) { + if (!$skiponboarding) { + return true; + } + // Wait for the onboarding modal to open, if any. $this->wait_for_pending_js(); From 93f8f048d16f71ece5171d22ad440cff2d0c645e Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 23 Sep 2021 17:10:22 +0200 Subject: [PATCH 137/220] MOBILE-3876 behat: Test that plugins work properly --- classes/output/mobile.php | 42 +++++++++++++++++++++++++++++++++++++ db/mobile.php | 34 ++++++++++++++++++++++++++++++ js/mobile/index.js | 5 +++++ tests/behat/plugins.feature | 16 ++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 classes/output/mobile.php create mode 100644 db/mobile.php create mode 100644 js/mobile/index.js create mode 100644 tests/behat/plugins.feature diff --git a/classes/output/mobile.php b/classes/output/mobile.php new file mode 100644 index 000000000..88732ab38 --- /dev/null +++ b/classes/output/mobile.php @@ -0,0 +1,42 @@ +. + +namespace local_moodlemobileapp\output; + +defined('MOODLE_INTERNAL') || die(); + +class mobile { + + /** + * Render index page. + * + * @return array View data. + */ + public static function view_index() { + $templates = [ + [ + 'id' => 'main', + 'html' => '

Hello!

', + ], + ]; + + $javascript = file_get_contents(__DIR__ . '/../../js/mobile/index.js'); + + return compact('templates', 'javascript'); + } + +} diff --git a/db/mobile.php b/db/mobile.php new file mode 100644 index 000000000..91b0def21 --- /dev/null +++ b/db/mobile.php @@ -0,0 +1,34 @@ +. + +$addons = [ + 'local_moodlemobileapp' => [ + 'handlers' => [ + 'index' => [ + 'delegate' => 'CoreMainMenuDelegate', + 'method' => 'view_index', + 'displaydata' => [ + 'title' => 'pluginname', + 'icon' => 'language', + ], + ], + ], + 'lang' => [ + ['pluginname', 'local_moodlemobileapp'], + ], + ], +]; diff --git a/js/mobile/index.js b/js/mobile/index.js new file mode 100644 index 000000000..4576f5024 --- /dev/null +++ b/js/mobile/index.js @@ -0,0 +1,5 @@ +this.CoreSitesProvider.getSite().then(site => { + const username = site.infos.username; + + document.getElementById('username').innerText = `, ${username}`; +}); diff --git a/tests/behat/plugins.feature b/tests/behat/plugins.feature new file mode 100644 index 000000000..501e5a707 --- /dev/null +++ b/tests/behat/plugins.feature @@ -0,0 +1,16 @@ +@app @javascript +Feature: Plugins work properly. + + Background: + Given the following "users" exist: + | username | + | studentusername | + + Scenario: See main menu button + When I enter the app + And I log in as "studentusername" + And I press the main menu button in the app + Then I should find "Moodle Mobile language strings" in the app + + When I press "Moodle Mobile language strings" in the app + Then I should find "studentusername" in the app From b7313ef7b3f8357b859c6336bdc162e7bca721d8 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 29 Sep 2021 14:14:48 +0200 Subject: [PATCH 138/220] MOBILE-3875 behat: Implement app listeners --- tests/behat/behat_app.php | 66 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 088961a64..25c857562 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -31,6 +31,23 @@ use Behat\Gherkin\Node\TableNode; use Behat\Mink\Exception\DriverException; use Behat\Mink\Exception\ExpectationException; +/** + * Behat app listener. + */ +interface behat_app_listener { + + /** + * Called when the app is loaded. + */ + function on_app_load(): void; + + /** + * Called before the app is unloaded. + */ + function on_app_unload(): void; + +} + /** * Mobile/desktop app steps definitions. * @@ -43,12 +60,36 @@ class behat_app extends behat_base { /** @var stdClass Object with data about launched Ionic instance (if any) */ protected static $ionicrunning = null; + /** @var array */ + protected static $listeners = []; + /** @var string URL for running Ionic server */ protected $ionicurl = ''; + /** @var bool Whether the app is running or not */ + protected $apprunning = false; + /** @var bool Checks whether the app is runing a legacy version (ionic 3) */ protected $islegacy; + /** + * Register listener. + * + * @param behat_app_listener $listener Listener. + * @return Closure Unregister function. + */ + public static function listen(behat_app_listener $listener): Closure { + self::$listeners[] = $listener; + + return function () use ($listener) { + $index = array_search($listener, self::$listeners); + + if ($index !== false) { + array_splice(self::$listeners, $index, 1); + } + }; + } + /** * Checks if the current OS is Windows, from the point of view of task-executing-and-killing. * @@ -365,6 +406,10 @@ class behat_app extends behat_base { $skiponboarding = $options['skiponboarding'] ?? true; if ($restart) { + if ($this->apprunning) { + $this->notify_unload(); + } + // Restart the browser and set its size. $this->getSession()->restart(); $this->resize_window('360x720', true); @@ -382,6 +427,9 @@ class behat_app extends behat_base { // Visit the Ionic URL. $this->getSession()->visit($this->ionicurl); + $this->notify_load(); + + $this->apprunning = true; } // Wait the application to load. @@ -938,4 +986,22 @@ class behat_app extends behat_base { return $text; } + /** + * Notify to listeners that the app was just loaded. + */ + private function notify_load(): void { + foreach (self::$listeners as $listener) { + $listener->on_app_load(); + } + } + + /** + * Notify to listeners that the app is about to be unloaded. + */ + private function notify_unload(): void { + foreach (self::$listeners as $listener) { + $listener->on_app_unload(); + } + } + } From 2937f8f1f2de1e5354e6df8149f1d72bc520d0dd Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 29 Sep 2021 14:26:14 +0200 Subject: [PATCH 139/220] MOBILE-3833 behat: Fix changing sites --- mod/login/tests/behat/app_basic_usage.feature | 2 ++ tests/behat/navigation_deeplinks.feature | 1 + 2 files changed, 3 insertions(+) diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index 6709d8c76..a8b683aae 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -35,6 +35,7 @@ Feature: Test basic usage of login in app And I log in as "student1" And I press the main menu button in the app And I press "Change site" in the app + And I wait the app to restart And I press "Add" in the app And I set the field "Your site" to "Wrong Site Address" in the app And I press enter in the app @@ -46,6 +47,7 @@ Feature: Test basic usage of login in app And I log in as "student1" And I press the main menu button in the app And I press "Change site" in the app + And I wait the app to restart Then I should find "Acceptance test site" in the app And I press "Delete" in the app And I press "Delete" near "Acceptance test site" in the app diff --git a/tests/behat/navigation_deeplinks.feature b/tests/behat/navigation_deeplinks.feature index 051ae52fc..1c1053ce2 100644 --- a/tests/behat/navigation_deeplinks.feature +++ b/tests/behat/navigation_deeplinks.feature @@ -27,6 +27,7 @@ Feature: It navigates properly using deep links. And I log in as "student2" And I press the main menu button in the app And I press "Log out" in the app + And I wait the app to restart And I press "Add" in the app And I set the field "Your site" to "$WWWROOT" in the app And I press "Connect to your site" in the app From 2adc7d51edafcd644d6f738b527b46f3de380967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 30 Sep 2021 16:47:06 +0200 Subject: [PATCH 140/220] MOBILE-3833 behat: Fix deep linking wait to start --- tests/behat/navigation_deeplinks.feature | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/behat/navigation_deeplinks.feature b/tests/behat/navigation_deeplinks.feature index 1c1053ce2..e4edc1631 100644 --- a/tests/behat/navigation_deeplinks.feature +++ b/tests/behat/navigation_deeplinks.feature @@ -35,6 +35,7 @@ Feature: It navigates properly using deep links. And I receive a push notification in the app for: | username | module | discussion | | student2 | forum | Forum topic | + And I wait the app to restart Then I should find "Reconnect" in the app When I set the field "Password" to "student2" in the app @@ -54,6 +55,7 @@ Feature: It navigates properly using deep links. | discussion | | Forum topic | And I log in as "student1" + And I wait loading to finish in the app Then I should find "Forum topic" in the app And I should find "Forum message" in the app But I should not find "Site home" in the app From 99e836d492c94524f4cf4a7734994276d0430124 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 4 Oct 2021 14:02:40 +0200 Subject: [PATCH 141/220] MOBILE-3833 behat: Fix editing mode toggle --- mod/course/tests/behat/app_basic_usage.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index de031bb6b..7e880db1d 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -495,7 +495,7 @@ Feature: Test basic usage of one course in app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" - And I press "Turn editing on" + And I click on "Edit mode" "checkbox" And I click on "Side panel" "button" And I follow "Add a block" And I follow "Text" From 3b5d57e02b53f60fca5d12f5270d6d86b5606db7 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 4 Oct 2021 17:13:40 +0200 Subject: [PATCH 142/220] MOBILE-3833 behat: use ngZone Using changeDetector caused some flaky tests throwing errors trying to use undefined variables. ngZone seems to work better. --- tests/behat/behat_app.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 25c857562..54ebb3d91 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -849,7 +849,7 @@ class behat_app extends behat_base { ); // Trigger Angular change detection - $session->executeScript($this->islegacy ? 'appRef.tick();' : 'changeDetector.detectChanges();'); + $session->executeScript($this->islegacy ? 'appRef.tick();' : 'ngZone.run(() => {});'); } /** @@ -862,7 +862,7 @@ class behat_app extends behat_base { $this->spin( function() use ($session) { - $session->executeScript($this->islegacy ? 'appRef.tick();' : 'changeDetector.detectChanges();'); + $session->executeScript($this->islegacy ? 'appRef.tick();' : 'ngZone.run(() => {});'); $nodes = $this->find_all('css', 'core-loading ion-spinner'); From 421c5b282a74de2365cdaa45662fd9d62bb95902 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 8 Oct 2021 15:11:02 +0200 Subject: [PATCH 143/220] MOBILE-3726 behat: Add tests for external links --- tests/behat/app_behat_runtime.js | 3 ++ tests/behat/behat_app.php | 33 ++++++++++++-- tests/behat/navigation_externallinks.feature | 48 ++++++++++++++++++++ 3 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 tests/behat/navigation_externallinks.feature diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 40a71cdf7..a21ac38e8 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -518,6 +518,9 @@ near: { text: 'Notifications' }, })[0]; break; + case 'page menu': + foundButton = findElementsBasedOnText({ text: 'Display options' })[0]; + break; default: return 'ERROR: Unsupported standard button type'; } diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 54ebb3d91..31583690a 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -789,14 +789,16 @@ class behat_app extends behat_base { /** * Check that the app opened a new browser tab. * - * @Given /^the app should( not)? have opened a browser tab$/ + * @Given /^the app should( not)? have opened a browser tab(?: with url "(?P[^"]+)")?$/ * @param bool $not + * @param string $urlpattern */ - public function the_app_should_have_opened_a_browser_tab(bool $not = false) { - $this->spin(function() use ($not) { - $openedbrowsertab = count($this->getSession()->getWindowNames()) === 2; + public function the_app_should_have_opened_a_browser_tab(bool $not = false, ?string $urlpattern = null) { + $this->spin(function() use ($not, $urlpattern) { + $windownames = $this->getSession()->getWindowNames(); + $openedbrowsertab = count($windownames) === 2; - if ($not === $openedbrowsertab) { + if ((!$not && !$openedbrowsertab) || ($not && $openedbrowsertab && is_null($urlpattern))) { throw new ExpectationException( $not ? 'Did not expect the app to have opened a browser tab' @@ -805,6 +807,22 @@ class behat_app extends behat_base { ); } + if (!is_null($urlpattern)) { + $this->getSession()->switchToWindow($windownames[1]); + $windowurl = $this->getSession()->getCurrentUrl(); + $windowhaspattern = preg_match("/$urlpattern/", $windowurl); + $this->getSession()->switchToWindow($windownames[0]); + + if ($not === $windowhaspattern) { + throw new ExpectationException( + $not + ? "Did not expect the app to have opened a browser tab with pattern '$urlpattern'" + : "Browser tab url does not match pattern '$urlpattern', it is '$windowurl'", + $this->getSession()->getDriver() + ); + } + } + return true; }); } @@ -895,6 +913,11 @@ class behat_app extends behat_base { if (count($names) !== 2) { throw new DriverException('Expected to see 2 tabs open, not ' . count($names)); } + // Make sure the browser tab is selected. + if ($this->getSession()->getWindowName() !== $names[1]) { + $this->getSession()->switchToWindow($names[1]); + } + $this->execute_script('window.close()'); $this->getSession()->switchToWindow($names[0]); } diff --git a/tests/behat/navigation_externallinks.feature b/tests/behat/navigation_externallinks.feature new file mode 100644 index 000000000..b3da3c3be --- /dev/null +++ b/tests/behat/navigation_externallinks.feature @@ -0,0 +1,48 @@ +@app @javascript +Feature: It opens external links properly. + + Background: + Given the following "users" exist: + | username | + | student1 | + And the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | + | forum | Test forum | Test forum | C1 | forum | + And the following forum discussions exist in course "Course 1": + | forum | user | name | message | + | Test forum | student1 | Forum topic | See moodle.org | + + Scenario: Click an external link + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Test forum" in the app + And I press "Forum topic" in the app + And I press "moodle.org" in the app + Then I should find "You are about to leave the app" in the app + + When I press "Cancel" in the app + And I press "moodle.org" in the app + And I press "OK" in the app + Then the app should have opened a browser tab with url "moodle.org" + + When I close the browser tab opened by the app + And I press the back button in the app + And I press the page menu button in the app + And I press "Open in browser" in the app + Then the app should have opened a browser tab + + When I close the browser tab opened by the app + And I press "Forum topic" in the app + And I press "moodle.org" in the app + And I select "Don't show again." in the app + And I press "OK" in the app + And I close the browser tab opened by the app + And I press "moodle.org" in the app + Then the app should have opened a browser tab with url "moodle.org" From ae1f9e578aaced4d2703a6d7fffa598b525c007c Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 21 Oct 2021 10:53:08 +0200 Subject: [PATCH 144/220] MOBILE-3898 behat: Remove generic transformers --- tests/behat/behat_app.php | 40 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 31583690a..35415822a 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -159,9 +159,10 @@ class behat_app extends behat_base { * * @Then /^I should( not)? find (".+") in the app$/ * @param bool $not - * @param object $locator + * @param string $locator */ - public function i_find_in_the_app(bool $not, object $locator) { + public function i_find_in_the_app(bool $not, string $locator) { + $locator = $this->parse_element_locator($locator); $locatorjson = json_encode($locator); $this->spin(function() use ($not, $locatorjson) { @@ -185,10 +186,11 @@ class behat_app extends behat_base { * Check if elements are selected in the app. * * @Then /^(".+") should( not)? be selected in the app$/ - * @param object $locator + * @param string $locator * @param bool $not */ - public function be_selected_in_the_app(object $locator, bool $not = false) { + public function be_selected_in_the_app(string $locator, bool $not = false) { + $locator = $this->parse_element_locator($locator); $locatorjson = json_encode($locator); $this->spin(function() use ($locatorjson, $not) { @@ -474,7 +476,7 @@ class behat_app extends behat_base { : $page->find('xpath', '//core-login-site-onboarding'); if ($element) { - $this->i_press_in_the_app($this->parse_element_locator('"Skip"')); + $this->i_press_in_the_app('"Skip"'); } // Login screen found. @@ -503,7 +505,7 @@ class behat_app extends behat_base { global $CFG; $this->i_set_the_field_in_the_app($this->islegacy ? 'campus.example.edu' : 'Your site', $CFG->wwwroot); - $this->i_press_in_the_app($this->parse_element_locator($this->islegacy ? '"Connect!"' : '"Connect to your site"')); + $this->i_press_in_the_app($this->islegacy ? '"Connect!"' : '"Connect to your site"'); $this->wait_for_pending_js(); } @@ -520,7 +522,7 @@ class behat_app extends behat_base { // Note there are two 'Log in' texts visible (the title and the button) so we have to use // a 'near' value here. - $this->i_press_in_the_app($this->parse_element_locator('"Log in" near "Forgotten"')); + $this->i_press_in_the_app('"Log in" near "Forgotten"'); // Wait until the main page appears. $this->spin( @@ -649,10 +651,11 @@ class behat_app extends behat_base { * distinguish visible items and the app always has many non-visible items in the DOM. * * @Then /^I press (".+") in the app$/ - * @param object $locator Element locator + * @param string $locator Element locator * @throws DriverException If the press doesn't work */ - public function i_press_in_the_app(object $locator) { + public function i_press_in_the_app(string $locator) { + $locator = $this->parse_element_locator($locator); $locatorjson = json_encode($locator); $this->spin(function() use ($locatorjson) { @@ -677,11 +680,12 @@ class behat_app extends behat_base { * * @Then /^I (unselect|select) (".+") in the app$/ * @param string $selectedtext - * @param object $locator + * @param string $locator * @throws DriverException If the press doesn't work */ - public function i_select_in_the_app(string $selectedtext, object $locator) { + public function i_select_in_the_app(string $selectedtext, string $locator) { $selected = $selectedtext === 'select' ? 'YES' : 'NO'; + $locator = $this->parse_element_locator($locator); $locatorjson = json_encode($locator); $this->spin(function() use ($selectedtext, $selected, $locatorjson) { @@ -936,11 +940,10 @@ class behat_app extends behat_base { /** * Parse an element locator string. * - * @Transform /^".+"$/ * @param string $text Element locator string. * @return object */ - public function parse_element_locator($text): object { + public function parse_element_locator(string $text): object { preg_match('/^"((?:[^"]|\\")*?)"(?: "([^"]*?)")?(?: near "((?:[^"]|\\")*?)"(?: "([^"]*?)")?)?$/', $text, $matches); $locator = [ @@ -958,17 +961,6 @@ class behat_app extends behat_base { return (object) $locator; } - /** - * Parse a negation string. - * - * @Transform /^not $/ - * @param string $not Negation string. - * @return bool - */ - public function parse_negation(string $not): bool { - return !empty($not); - } - /** * Replaces $WWWROOT for the url of the Moodle site. * From 31c63a542e256705092efbe5070b2b719298556a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 21 Oct 2021 16:06:58 +0200 Subject: [PATCH 145/220] MOBILE-3686: Adapt tests to new course list page --- mod/courses/tests/behat/app_basic_usage.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index d0a6e3dc7..c265717f8 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -86,7 +86,7 @@ Feature: Test basic usage of courses in app And I set the field "Search" to "Course 4" in the app And I press "Search" "button" in the app Then I should find "Course 4" in the app - And the header should be "Search courses" in the app + And the header should be "Available courses" in the app When I press "Course 4" in the app Then I should find "Course 4" in the app From ec008a9e1e25fc73baf292fe93d27ba74c58aba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 3 Nov 2021 12:31:04 +0100 Subject: [PATCH 146/220] MOBILE-3807: Adapt tests to new account menu --- mod/login/tests/behat/app_basic_usage.feature | 34 +++++++++++++------ .../tests/behat/app_quiz_navigation.feature | 5 --- tests/behat/app_behat_runtime.js | 5 ++- tests/behat/behat_app.php | 2 +- tests/behat/navigation_deeplinks.feature | 4 +-- tests/behat/navigation_splitview.feature | 33 +++++++++++------- 6 files changed, 50 insertions(+), 33 deletions(-) diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index a8b683aae..c1b1f5747 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -17,7 +17,7 @@ Feature: Test basic usage of login in app | student2 | C1 | student | | teacher1 | C1 | editingteacher | - Scenario: Add a new site in the app & Site name in displayed when adding a new site + Scenario: Add a new account in the app & Site name in displayed when adding a new account When I enter the app And I press the back button in the app And I set the field "Your site" to "$WWWROOT" in the app @@ -30,28 +30,40 @@ Feature: Test basic usage of login in app Then I should find "Acceptance test site" in the app But I should not find "Log in" in the app - Scenario: Add a non existing site + Scenario: Add a non existing account When I enter the app And I log in as "student1" - And I press the main menu button in the app - And I press "Change site" in the app + And I press the accounts menu button in the app + And I press "Log out" in the app And I wait the app to restart - And I press "Add" in the app + And I press "Add a new account" in the app And I set the field "Your site" to "Wrong Site Address" in the app And I press enter in the app Then I should find "Cannot connect" in the app And I should find "Wrong Site Address" in the app - Scenario: Delete a site + Scenario: Add a non existing account from accounts switcher When I enter the app And I log in as "student1" - And I press the main menu button in the app - And I press "Change site" in the app + And I press the accounts menu button in the app + And I press "Switch account" in the app + And I press "Add a new account" in the app + And I wait the app to restart + And I set the field "Your site" to "Wrong Site Address" in the app + And I press enter in the app + Then I should find "Cannot connect" in the app + And I should find "Wrong Site Address" in the app + + Scenario: Delete an account + When I enter the app + And I log in as "student1" + And I press the accounts menu button in the app + And I press "Log out" in the app And I wait the app to restart Then I should find "Acceptance test site" in the app - And I press "Delete" in the app - And I press "Delete" near "Acceptance test site" in the app - And I press "Delete" near "Are you sure you want to delete the site Acceptance test site?" in the app + And I press "Edit accounts list" in the app + And I press "Remove account" near "Acceptance test site" in the app + And I press "Delete" near "Are you sure you want to remove the account on Acceptance test site?" in the app Then I should find "Connect to Moodle" in the app But I should not find "Acceptance test site" in the app diff --git a/mod/quiz/tests/behat/app_quiz_navigation.feature b/mod/quiz/tests/behat/app_quiz_navigation.feature index cf8a69dd4..acf59c360 100644 --- a/mod/quiz/tests/behat/app_quiz_navigation.feature +++ b/mod/quiz/tests/behat/app_quiz_navigation.feature @@ -63,8 +63,3 @@ Feature: Attempt a quiz in app And I press "Submit all and finish" in the app And I press "OK" near "Once you submit" in the app And I should find "Review" in the app - And I press "Home" in the app - And I should find "Are you sure" in the app - And I should find "OK" in the app - And I press "OK" in the app - And I should find "Acceptance test site" in the app diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index a21ac38e8..0584a4eb3 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -514,10 +514,13 @@ break; case 'main menu': foundButton = findElementsBasedOnText({ - text: 'more', + text: 'More', near: { text: 'Notifications' }, })[0]; break; + case 'accounts menu' : + foundButton = findElementsBasedOnText({ text: 'Account' })[0]; + break; case 'page menu': foundButton = findElementsBasedOnText({ text: 'Display options' })[0]; break; diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 35415822a..ddf4a9ea3 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -541,7 +541,7 @@ class behat_app extends behat_base { /** * Presses standard buttons in the app. * - * @Given /^I press the (back|main menu|page menu) button in the app$/ + * @Given /^I press the (back|main menu|page menu|accounts menu) button in the app$/ * @param string $button Button type * @throws DriverException If the button push doesn't work */ diff --git a/tests/behat/navigation_deeplinks.feature b/tests/behat/navigation_deeplinks.feature index e4edc1631..68d1ef148 100644 --- a/tests/behat/navigation_deeplinks.feature +++ b/tests/behat/navigation_deeplinks.feature @@ -25,10 +25,10 @@ Feature: It navigates properly using deep links. Scenario: Receive a push notification When I enter the app And I log in as "student2" - And I press the main menu button in the app + And I press the accounts menu button in the app And I press "Log out" in the app And I wait the app to restart - And I press "Add" in the app + And I press "Add a new account" in the app And I set the field "Your site" to "$WWWROOT" in the app And I press "Connect to your site" in the app And I log in as "student1" diff --git a/tests/behat/navigation_splitview.feature b/tests/behat/navigation_splitview.feature index 78ecda825..4648b023f 100644 --- a/tests/behat/navigation_splitview.feature +++ b/tests/behat/navigation_splitview.feature @@ -24,12 +24,12 @@ Feature: It navigates properly in pages with a split-view component. Scenario: Navigate in grades tab on mobile - # Open more tab + # Open accounts menu Given I enter the app And I log in as "student1" - And I press the main menu button in the app + And I press the accounts menu button in the app - # Open grades tab + # Open grades page When I press "Grades" in the app Then the header should be "Grades" in the app And I should find "Course 1" in the app @@ -51,7 +51,7 @@ Feature: It navigates properly in pages with a split-view component. Then the header should be "Grades" in the app And I should find "Grade category C1" in the app - # Go back to grades tab + # Go back to grades page When I press the back button in the app Then the header should be "Grades" in the app And I should find "Course 1" in the app @@ -73,26 +73,27 @@ Feature: It navigates properly in pages with a split-view component. Then the header should be "Grades" in the app And I should find "Grade category C2" in the app - # Go back to grades tab + # Go back to grades page When I press the back button in the app Then the header should be "Grades" in the app And I should find "Course 1" in the app And I should find "Course 2" in the app - # Go back to more tab + # Go back to main page When I press the back button in the app - Then I should find "Grades" in the app - And I should find "App settings" in the app + Then I should find "Acceptance test site" in the app + And I should find "Account" in the app But I should not find "Back" in the app Scenario: Navigate in grades tab on tablet - # Open more tab + # Open accounts menu Given I enter the app And I change viewport size to "1200x640" And I log in as "student1" + And I press the accounts menu button in the app - # Open grades tab + # Open grades page When I press "Grades" in the app Then the header should be "Grades" in the app And I should find "Course 1" in the app @@ -106,7 +107,7 @@ Feature: It navigates properly in pages with a split-view component. And I should find "20" near "Range" in the app And I should find "40" near "Range" in the app - # Go back to grades tab + # Go back to grades page When I press the back button in the app Then the header should be "Grades" in the app And I should find "Course 1" in the app @@ -125,9 +126,15 @@ Feature: It navigates properly in pages with a split-view component. And I should find "60" near "Range" in the app And I should find "80" near "Range" in the app - # Go back to grades tab + # Go back to grades page When I press the back button in the app Then the header should be "Grades" in the app And I should find "Course 1" in the app And I should find "Course 2" in the app - But I should not find "Back" in the app + And I should find "Back" in the app + + # Go back to main page + When I press the back button in the app + Then I should find "Acceptance test site" in the app + And I should find "Account" in the app + But I should not find "Back" in the app \ No newline at end of file From 2aed85bb1313db9c29561fccb68ea609bec14188 Mon Sep 17 00:00:00 2001 From: Mark Johnson Date: Wed, 10 Nov 2021 14:59:32 +0000 Subject: [PATCH 147/220] Remove XHR from pending JS on exception --- tests/behat/app_behat_runtime.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 0584a4eb3..831c354df 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -98,15 +98,20 @@ var index = requestIndex++; var key = 'httprequest-' + index; - // Add to the list of pending requests. - addPending(key); + try { + // Add to the list of pending requests. + addPending(key); - // Detect when it finishes and remove it from the list. - this.addEventListener('loadend', function() { + // Detect when it finishes and remove it from the list. + this.addEventListener('loadend', function() { + removePending(key); + }); + + return realOpen.apply(this, arguments); + } catch (e) { removePending(key); - }); - - return realOpen.apply(this, arguments); + throw e; + } }; var waitingBlocked = false; From 1ead9612a3df2d52774ff3f4431d0e5e7af43453 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 9 Nov 2021 16:06:13 +0100 Subject: [PATCH 148/220] MOBILE-3905 behat: Test swipe navigation --- tests/behat/app_behat_runtime.js | 20 +++++++- tests/behat/behat_app.php | 12 +++++ tests/behat/navigation_gestures.feature | 63 +++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 tests/behat/navigation_gestures.feature diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 0584a4eb3..83bd8b945 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -352,7 +352,7 @@ } } - return [...uniqueElements]; + return Array.from(uniqueElements); }; /** @@ -793,6 +793,23 @@ return 'OK'; }; + /** + * Get an Angular component instance. + * + * @param {string} selector Element selector + * @param {string} className Constructor class name + * @return {object} Component instance + */ + var behatGetComponentInstance = function(selector, className) { + const activeElement = Array.from(document.querySelectorAll(`.ion-page:not(.ion-page-hidden) ${selector}`)).pop(); + + if (!activeElement || !activeElement.__ngContext__) { + return null; + } + + return activeElement.__ngContext__.find(node => node?.constructor?.name === className); + }; + // Make some functions publicly available for Behat to call. window.behat = { pressStandard : behatPressStandard, @@ -802,5 +819,6 @@ press : behatPress, setField : behatSetField, getHeader : behatGetHeader, + getComponentInstance: behatGetComponentInstance, }; })(); diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index ddf4a9ea3..4e1221a9d 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -182,6 +182,18 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } + /** + * Trigger swipe gesture. + * + * @When /^I swipe to the (left|right) in the app$/ + * @param string $direction + */ + public function i_swipe_in_the_app(string $direction) { + $method = 'swipe' . ucwords($direction); + + $this->evaluate_script("behat.getComponentInstance('core-swipe-navigation', 'CoreSwipeNavigationComponent').$method()"); + } + /** * Check if elements are selected in the app. * diff --git a/tests/behat/navigation_gestures.feature b/tests/behat/navigation_gestures.feature new file mode 100644 index 000000000..e51465d27 --- /dev/null +++ b/tests/behat/navigation_gestures.feature @@ -0,0 +1,63 @@ +@app @javascript +Feature: It navigates using gestures. + + Background: + Given the following "users" exist: + | username | firstname | lastname | + | student1 | Student | First | + | teacher1 | Teacher | First | + | student2 | Student | Second | + | teacher2 | Teacher | Second | + | student3 | Student | Third | + And the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | teacher1 | C1 | teacher | + | student2 | C1 | student | + | teacher2 | C1 | teacher | + | student3 | C1 | student | + + Scenario: Swipe between participants + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Participants" in the app + And I press "Student First" in the app + And I swipe to the left in the app + Then I should find "Teacher First" in the app + + When I swipe to the left in the app + Then I should find "Student Second" in the app + + When I swipe to the right in the app + Then I should find "Teacher First" in the app + + When I swipe to the right in the app + Then I should find "Student First" in the app + + When I swipe to the right in the app + Then I should find "Student First" in the app + + Scenario: Swipe between filtered participants + When I enter the app + And I log in as "student1" + And I press "Course 1" near "Course overview" in the app + And I press "Participants" in the app + And I press "Search" in the app + And I set the field "Search" to "student" in the app + And I press "Search" "button" near "Clear search" in the app + And I press "Student First" in the app + And I swipe to the left in the app + Then I should find "Student Second" in the app + + When I swipe to the left in the app + Then I should find "Student Third" in the app + + When I swipe to the right in the app + Then I should find "Student Second" in the app + + When I swipe to the right in the app + Then I should find "Student First" in the app From 0b774fc53cb43e748544e15311e4e2ce9ea89cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 17 Nov 2021 10:47:55 +0100 Subject: [PATCH 149/220] MOBILE-3914 blocks: Adapt tests to new block drawer --- mod/course/tests/behat/app_basic_usage.feature | 3 ++- mod/courses/tests/behat/app_basic_usage.feature | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 7e880db1d..7fe904f2c 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -486,7 +486,7 @@ Feature: Test basic usage of one course in app And I should find "Test workshop name" in the app # TODO remove LMS UI steps in app tests - Scenario: View blocks below/beside contents also when All sections selected + Scenario: View blocks on drawer Given I enter the app And I log in as "teacher1" And I press "Course 1" near "Course overview" in the app @@ -527,6 +527,7 @@ Feature: Test basic usage of one course in app And I should find "Test lesson name" in the app And I should find "Test scorm name" in the app And I should find "Test workshop name" in the app + Then I press "Open block drawer" in the app And I should find "HTML title test" in the app And I should find "body test" in the app And I should find "Activities" in the app diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index c265717f8..0bb029c26 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -105,6 +105,7 @@ Feature: Test basic usage of courses in app # Configure assignment as teacher When I enter the app And I log in as "teacher1" + Then I press "Open block drawer" in the app Then I should find "Timeline" in the app Given I press "Course 1" near "Course overview" in the app @@ -124,6 +125,7 @@ Feature: Test basic usage of courses in app # Submit assignment as student When I enter the app And I log in as "student1" + Then I press "Open block drawer" in the app And I press "Add submission" in the app Then the header should be "assignment" in the app And I should find "Test assignment description" in the app @@ -143,6 +145,7 @@ Feature: Test basic usage of courses in app # Grade assignment as teacher When I enter the app And I log in as "teacher1" + Then I press "Open block drawer" in the app And I press "Grade" in the app Then the header should be "assignment" in the app And I should find "Test assignment description" in the app From fc96a23e8a38bd4fcfc4f6ca21357d9768b2be91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 24 Nov 2021 10:47:10 +0100 Subject: [PATCH 150/220] MOBILE-3810 behat: Remove legacy code --- tests/behat/app_behat_runtime.js | 363 +++++++++---------------------- tests/behat/behat_app.php | 29 +-- 2 files changed, 112 insertions(+), 280 deletions(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index de3643bc9..d26f86651 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -1,7 +1,7 @@ (function() { // Set up the M object - only pending_js is implemented. window.M = window.M ? window.M : {}; - var M = window.M; + const M = window.M; M.util = M.util ? M.util : {}; M.util.pending_js = M.util.pending_js ? M.util.pending_js : []; // eslint-disable-line camelcase @@ -11,9 +11,9 @@ * * @param {string} text Information to log */ - var log = function() { - var now = new Date(); - var nowFormatted = String(now.getHours()).padStart(2, '0') + ':' + + const log = function() { + const now = new Date(); + const nowFormatted = String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0') + ':' + String(now.getSeconds()).padStart(2, '0') + '.' + String(now.getMilliseconds()).padStart(2, '0'); @@ -26,7 +26,7 @@ * @param {function} target function to run * @param {number} count Number of times to do setTimeout (leave blank for 10) */ - var runAfterEverything = function(target, count) { + const runAfterEverything = function(target, count) { if (count === undefined) { count = 10; } @@ -45,7 +45,7 @@ * * @param {string} key Key to add */ - var addPending = function(key) { + const addPending = function(key) { // Add a special DELAY entry whenever another entry is added. if (window.M.util.pending_js.length == 0) { window.M.util.pending_js.push('DELAY'); @@ -61,7 +61,7 @@ * * @param {string} key Key to remove */ - var removePending = function(key) { + const removePending = function(key) { // Remove the key immediately. window.M.util.pending_js = window.M.util.pending_js.filter(function(x) { // eslint-disable-line camelcase return x !== key; @@ -86,17 +86,17 @@ /** * Adds a pending key to the array, but removes it after some setTimeouts finish. */ - var addPendingDelay = function() { + const addPendingDelay = function() { addPending('...'); removePending('...'); }; // Override XMLHttpRequest to mark things pending while there is a request waiting. - var realOpen = XMLHttpRequest.prototype.open; - var requestIndex = 0; + const realOpen = XMLHttpRequest.prototype.open; + let requestIndex = 0; XMLHttpRequest.prototype.open = function() { - var index = requestIndex++; - var key = 'httprequest-' + index; + const index = requestIndex++; + const key = 'httprequest-' + index; try { // Add to the list of pending requests. @@ -108,20 +108,20 @@ }); return realOpen.apply(this, arguments); - } catch (e) { + } catch (error) { removePending(key); - throw e; + throw error; } }; - var waitingBlocked = false; + let waitingBlocked = false; /** * Checks if a loading spinner is present and visible; if so, adds it to the pending array * (and if not, removes it). */ - var checkUIBlocked = function() { - var blocked = document.querySelector('span.core-loading-spinner, ion-loading, .click-block-active'); + const checkUIBlocked = function() { + const blocked = document.querySelector('span.core-loading-spinner, ion-loading, .click-block-active'); if (blocked && blocked.offsetParent) { if (!waitingBlocked) { addPending('blocked'); @@ -142,8 +142,8 @@ // of the animations are set to 500ms so we allow it to continue from 500ms after any DOM // change. - var recentMutation = false; - var lastMutation; + let recentMutation = false; + let lastMutation; /** * Called from the mutation callback to remove the pending tag after 500ms if nothing else @@ -152,7 +152,7 @@ * This will be called after 500ms, then every 100ms until there have been no mutation events * for 500ms. */ - var pollRecentMutation = function() { + const pollRecentMutation = function() { if (Date.now() - lastMutation > 500) { recentMutation = false; removePending('dom-mutation'); @@ -164,7 +164,7 @@ /** * Mutation callback, called whenever the DOM is mutated. */ - var mutationCallback = function() { + const mutationCallback = function() { lastMutation = Date.now(); if (!recentMutation) { recentMutation = true; @@ -176,7 +176,7 @@ }; // Set listener using the mutation callback. - var observer = new MutationObserver(mutationCallback); + const observer = new MutationObserver(mutationCallback); observer.observe(document, {attributes: true, childList: true, subtree: true}); /** @@ -186,7 +186,7 @@ * @param {HTMLElement} container Container * @returns {boolean} Whether the element is visible or not */ - var isElementVisible = (element, container) => { + const isElementVisible = (element, container) => { if (element.getAttribute('aria-hidden') === 'true' || getComputedStyle(element).display === 'none') return false; @@ -207,7 +207,7 @@ * @param {HTMLElement} container Container * @returns {boolean} Whether the element is selected or not */ - var isElementSelected = (element, container) => { + const isElementSelected = (element, container) => { const ariaCurrent = element.getAttribute('aria-current'); if ( (ariaCurrent && ariaCurrent !== 'false') || @@ -223,31 +223,6 @@ return isElementSelected(parentElement, container); }; - /** - * Generic shared function to find possible xpath matches within the document, that are visible, - * and then process them using a callback function. - * - * @param {string} xpath Xpath to use - * @param {function} process Callback function that handles each matched node - */ - var findPossibleMatches = function(xpath, process) { - var select = 'ion-alert, ion-popover, ion-action-sheet, core-ion-tab.show-tab ion-page.show-page, ion-page.show-page, html'; - var parent = document.querySelector(select); - var matches = document.evaluate(xpath, parent || document); - while (true) { - var match = matches.iterateNext(); - if (!match) { - break; - } - // Skip invisible text nodes. - if (!match.offsetParent) { - continue; - } - - process(match); - } - }; - /** * Finds elements within a given container. * @@ -255,7 +230,7 @@ * @param {string} text Text to look for * @return {HTMLElement} Elements containing the given text */ - var findElementsBasedOnTextWithin = (container, text) => { + const findElementsBasedOnTextWithin = (container, text) => { const elements = []; const attributesSelector = `[aria-label*="${text}"], a[title*="${text}"], img[alt*="${text}"]`; @@ -342,7 +317,7 @@ * @param {Array} elements Elements list. * @return {Array} Top ancestors. */ - var getTopAncestors = function(elements) { + const getTopAncestors = function(elements) { const uniqueElements = new Set(elements); for (const element of uniqueElements) { @@ -366,7 +341,7 @@ * @param {HTMLElement} element Element. * @return {HTMLElement} Parent element. */ - var getParentElement = function(element) { + const getParentElement = function(element) { return element.parentElement || (element.getRootNode() && element.getRootNode().host) || null; }; @@ -376,7 +351,7 @@ * @param {object} locator Element locator. * @return {HTMLElement} Found elements */ - var findElementsBasedOnText = function(locator) { + const findElementsBasedOnText = function(locator) { const topContainer = document.querySelector('ion-alert, ion-popover, ion-action-sheet, core-ion-tab.show-tab ion-page.show-page, ion-page.show-page, html'); let container = topContainer; @@ -417,48 +392,39 @@ * * @param {HTMLElement} element Element to press. */ - var pressElement = function(element) { - if (window.BehatMoodleAppLegacy) { - var mainContent = getNavCtrl().getActive().contentRef().nativeElement; - var rect = element.getBoundingClientRect(); + const pressElement = function(element) { + // Scroll the item into view. + element.scrollIntoView(false); - // Scroll the item into view. - mainContent.scrollTo(rect.x, rect.y); + const rect = element.getBoundingClientRect(); - // Simulate a mouse click on the button. - var eventOptions = { - clientX: rect.left + rect.width / 2, - clientY: rect.top + rect.height / 2, - bubbles: true, - view: window, - cancelable: true, - }; - setTimeout(() => element.dispatchEvent(new MouseEvent('mousedown', eventOptions)), 0); - setTimeout(() => element.dispatchEvent(new MouseEvent('mouseup', eventOptions)), 0); - setTimeout(() => element.dispatchEvent(new MouseEvent('click', eventOptions)), 0); - } else { - // Scroll the item into view. - element.scrollIntoView(); + // Simulate a mouse click on the button. + const eventOptions = { + clientX: rect.left + rect.width / 2, + clientY: rect.top + rect.height / 2, + bubbles: true, + view: window, + cancelable: true, + }; - // Events don't bubble up across Shadow DOM boundaries, and some buttons - // may not work without doing this. - const parentElement = getParentElement(element); + // Events don't bubble up across Shadow DOM boundaries, and some buttons + // may not work without doing this. + const parentElement = getParentElement(element); - if (parentElement && parentElement.matches('ion-button, ion-back-button')) { - element = parentElement; - } - - // There are some buttons in the app that don't respond to click events, for example - // buttons using the core-supress-events directive. That's why we need to send both - // click and mouse events. - element.dispatchEvent(new MouseEvent('mousedown', eventOptions)); - - setTimeout(() => { - element.dispatchEvent(new MouseEvent('mouseup', eventOptions)); - element.click(); - }, 300); + if (parentElement && parentElement.matches('ion-button, ion-back-button')) { + element = parentElement; } + // There are some buttons in the app that don't respond to click events, for example + // buttons using the core-supress-events directive. That's why we need to send both + // click and mouse events. + element.dispatchEvent(new MouseEvent('mousedown', eventOptions)); + + setTimeout(() => { + element.dispatchEvent(new MouseEvent('mouseup', eventOptions)); + element.click(); + }, 300); + // Mark busy until the button click finishes processing. addPendingDelay(); }; @@ -469,69 +435,30 @@ * @param {string} button Type of button to press * @return {string} OK if successful, or ERROR: followed by message */ - var behatPressStandard = function(button) { + const behatPressStandard = function(button) { log('Action - Click standard button: ' + button); // Find button - var foundButton = null; + let foundButton = null; - if (window.BehatMoodleAppLegacy) { - var selector; - switch (button) { - case 'back' : - selector = 'ion-navbar > button.back-button-md'; - break; - case 'main menu' : - // Change in app version 3.8. - selector = 'page-core-mainmenu .tab-button > ion-icon[aria-label=more], ' + - 'page-core-mainmenu .tab-button > ion-icon[aria-label=menu]'; - break; - case 'page menu' : - // This lang string was changed in app version 3.6. - selector = 'core-context-menu > button[aria-label=Info], ' + - 'core-context-menu > button[aria-label=Information], ' + - 'core-context-menu > button[aria-label="Display options"]'; - break; - default: - return 'ERROR: Unsupported standard button type'; - } - var buttons = Array.from(document.querySelectorAll(selector)); - var tooMany = false; - buttons.forEach(function(button) { - if (button.offsetParent) { - if (foundButton === null) { - foundButton = button; - } else { - tooMany = true; - } - } - }); - if (!foundButton) { - return 'ERROR: Could not find button'; - } - if (tooMany) { - return 'ERROR: Found too many buttons'; - } - } else { - switch (button) { - case 'back': - foundButton = findElementsBasedOnText({ text: 'Back' })[0]; - break; - case 'main menu': - foundButton = findElementsBasedOnText({ - text: 'More', - near: { text: 'Notifications' }, - })[0]; - break; - case 'accounts menu' : - foundButton = findElementsBasedOnText({ text: 'Account' })[0]; - break; - case 'page menu': - foundButton = findElementsBasedOnText({ text: 'Display options' })[0]; - break; - default: - return 'ERROR: Unsupported standard button type'; - } + switch (button) { + case 'back': + foundButton = findElementsBasedOnText({ text: 'Back' })[0]; + break; + case 'main menu': + foundButton = findElementsBasedOnText({ + text: 'More', + near: { text: 'Notifications' }, + })[0]; + break; + case 'accounts menu' : + foundButton = findElementsBasedOnText({ text: 'Account' })[0]; + break; + case 'page menu': + foundButton = findElementsBasedOnText({ text: 'Display options' })[0]; + break; + default: + return 'ERROR: Unsupported standard button type'; } // Click button @@ -545,28 +472,22 @@ * * @return {string} OK if successful, or ERROR: followed by message */ - var behatClosePopup = function() { + const behatClosePopup = function() { log('Action - Close popup'); - var backdrops = Array.from(document.querySelectorAll('ion-backdrop')); - var found = null; - var tooMany = false; - backdrops.forEach(function(backdrop) { - if (backdrop.offsetParent) { - if (found === null) { - found = backdrop; - } else { - tooMany = true; - } - } + let backdrops = Array.from(document.querySelectorAll('ion-backdrop')); + backdrops = backdrops.filter(function(backdrop) { + return !!backdrop.offsetParent; }); - if (!found) { + + if (!backdrops.length) { return 'ERROR: Could not find backdrop'; } - if (tooMany) { + if (backdrops.length > 1) { return 'ERROR: Found too many backdrops'; } - found.click(); + const backdrop = backdrops[0]; + backdrop.click(); // Mark busy until the click finishes processing. addPendingDelay(); @@ -580,7 +501,7 @@ * @param {object} locator Element locator. * @return {string} OK if successful, or ERROR: followed by message */ - var behatFind = function(locator) { + const behatFind = function(locator) { log('Action - Find', locator); try { @@ -596,30 +517,13 @@ } }; - /** - * Get main navigation controller. - * - * @return {Object} main navigation controller. - */ - var getNavCtrl = function() { - var mainNav = window.appProvider.appCtrl.getRootNavs()[0].getActiveChildNav(); - if (mainNav && mainNav.tabsIds.length && mainNav.firstSelectedTab) { - var tabPos = mainNav.tabsIds.indexOf(mainNav.firstSelectedTab); - if (tabPos !== -1 && mainNav._tabs && mainNav._tabs.length > tabPos) { - return mainNav._tabs[tabPos]; - } - } - // Fallback to return main nav - this will work but will overlay current tab. - return window.appProvider.appCtrl.getRootNavs()[0]; - }; - /** * Check whether an item is selected or not. * * @param {object} locator Element locator. * @return {string} YES or NO if successful, or ERROR: followed by message */ - var behatIsSelected = function(locator) { + const behatIsSelected = function(locator) { log('Action - Is Selected', locator); try { @@ -637,10 +541,10 @@ * @param {object} locator Element locator. * @return {string} OK if successful, or ERROR: followed by message */ - var behatPress = function(locator) { + const behatPress = function(locator) { log('Action - Press', locator); - var found; + let found; try { found = findElementsBasedOnText(locator)[0]; @@ -661,28 +565,22 @@ * * @return {string} OK: followed by header text if successful, or ERROR: followed by message. */ - var behatGetHeader = function() { + const behatGetHeader = function() { log('Action - Get header'); - var result = null; - var resultCount = 0; - var titles = Array.from(document.querySelectorAll('ion-header ion-title, ion-header h1')); - titles.forEach(function(title) { - if ( - (window.BehatMoodleAppLegacy && title.offsetParent) || - (!window.BehatMoodleAppLegacy && isElementVisible(title, document.body)) - ) { - result = title.innerText.trim(); - resultCount++; - } + let titles = Array.from(document.querySelectorAll('ion-header ion-title, ion-header h1')); + titles = titles.filter(function(title) { + return isElementVisible(title, document.body); }); + - if (resultCount > 1) { + if (titles.length > 1) { return 'ERROR: Too many possible titles'; - } else if (!resultCount) { + } else if (!titles.length) { return 'ERROR: No title found'; } else { - return 'OK:' + result; + const title = titles[0].innerText.trim(); + return 'OK:' + title; } }; @@ -695,67 +593,18 @@ * @param {string} value New value * @return {string} OK or ERROR: followed by message */ - var behatSetField = function(field, value) { + const behatSetField = function(field, value) { log('Action - Set field ' + field + ' to: ' + value); - if (window.BehatMoodleAppLegacy) { - // Find input(s) with given placeholder. - var escapedText = field.replace('"', '""'); - var exactMatches = []; - var anyMatches = []; - findPossibleMatches( - '//input[contains(@placeholder, "' + escapedText + '")] |' + - '//textarea[contains(@placeholder, "' + escapedText + '")] |' + - '//core-rich-text-editor/descendant::div[contains(@data-placeholder-text, "' + - escapedText + '")]', function(match) { - // Add to array depending on if it's an exact or partial match. - var placeholder; - if (match.nodeName === 'DIV') { - placeholder = match.getAttribute('data-placeholder-text'); - } else { - placeholder = match.getAttribute('placeholder'); - } - if (placeholder.trim() === field) { - exactMatches.push(match); - } else { - anyMatches.push(match); - } - }); - - // Select the resulting match. - var found = null; - do { - // If there is an exact text match, use that (regardless of other matches). - if (exactMatches.length > 1) { - return 'ERROR: Too many exact placeholder matches for text'; - } else if (exactMatches.length) { - found = exactMatches[0]; - break; - } - - // If there is one partial text match, use that. - if (anyMatches.length > 1) { - return 'ERROR: Too many partial placeholder matches for text'; - } else if (anyMatches.length) { - found = anyMatches[0]; - break; - } - } while (false); - - if (!found) { - return 'ERROR: No matches for text'; - } - } else { - found = findElementsBasedOnText({ text: field, selector: 'input, textarea, [contenteditable="true"]' })[0]; - - if (!found) { - return 'ERROR: No matches for text'; - } + + const found = findElementsBasedOnText({ text: field, selector: 'input, textarea, [contenteditable="true"]' })[0]; + if (!found) { + return 'ERROR: No matches for text'; } // Functions to get/set value depending on field type. - var setValue; - var getValue; + let setValue; + let getValue; switch (found.nodeName) { case 'INPUT': case 'TEXTAREA': @@ -777,7 +626,7 @@ } // Pretend we have cut and pasted the new text. - var event; + let event; if (getValue() !== '') { event = new InputEvent('input', {bubbles: true, view: window, cancelable: true, inputType: 'devareByCut'}); @@ -805,7 +654,7 @@ * @param {string} className Constructor class name * @return {object} Component instance */ - var behatGetComponentInstance = function(selector, className) { + const behatGetComponentInstance = function(selector, className) { const activeElement = Array.from(document.querySelectorAll(`.ion-page:not(.ion-page-hidden) ${selector}`)).pop(); if (!activeElement || !activeElement.__ngContext__) { diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 4e1221a9d..b4afc627c 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -69,9 +69,6 @@ class behat_app extends behat_base { /** @var bool Whether the app is running or not */ protected $apprunning = false; - /** @var bool Checks whether the app is runing a legacy version (ionic 3) */ - protected $islegacy; - /** * Register listener. * @@ -432,13 +429,6 @@ class behat_app extends behat_base { $this->ionicurl = $this->start_or_reuse_ionic(); } - // Check whether the app is running a legacy version. - $json = @file_get_contents("{$this->ionicurl}/assets/env.json") ?: @file_get_contents("{$this->ionicurl}/config.json"); - $data = json_decode($json); - $appversion = $data->build->version ?? str_replace('-dev', '', $data->versionname); - - $this->islegacy = version_compare($appversion, '3.9.5', '<'); - // Visit the Ionic URL. $this->getSession()->visit($this->ionicurl); $this->notify_load(); @@ -453,10 +443,7 @@ class behat_app extends behat_base { if ($title) { $text = $title->getHtml(); - if ( - ($this->islegacy && $text === 'Moodle Desktop') || - (!$this->islegacy && $text === 'Moodle App') - ) { + if ($text === 'Moodle App') { return true; } } @@ -465,8 +452,6 @@ class behat_app extends behat_base { }, false, 60); // Run the scripts to install Moodle 'pending' checks. - $islegacyboolean = $this->islegacy ? 'true' : 'false'; - $this->execute_script("window.BehatMoodleAppLegacy = $islegacyboolean;"); $this->execute_script(file_get_contents(__DIR__ . '/app_behat_runtime.js')); if ($restart) { @@ -483,9 +468,7 @@ class behat_app extends behat_base { // Wait for the onboarding modal to open, if any. $this->wait_for_pending_js(); - $element = $this->islegacy - ? $page->find('xpath', '//page-core-login-site-onboarding') - : $page->find('xpath', '//core-login-site-onboarding'); + $element = $page->find('xpath', '//core-login-site-onboarding'); if ($element) { $this->i_press_in_the_app('"Skip"'); @@ -516,8 +499,8 @@ class behat_app extends behat_base { global $CFG; - $this->i_set_the_field_in_the_app($this->islegacy ? 'campus.example.edu' : 'Your site', $CFG->wwwroot); - $this->i_press_in_the_app($this->islegacy ? '"Connect!"' : '"Connect to your site"'); + $this->i_set_the_field_in_the_app('Your site', $CFG->wwwroot); + $this->i_press_in_the_app('"Connect to your site"'); $this->wait_for_pending_js(); } @@ -883,7 +866,7 @@ class behat_app extends behat_base { ); // Trigger Angular change detection - $session->executeScript($this->islegacy ? 'appRef.tick();' : 'ngZone.run(() => {});'); + $session->executeScript('ngZone.run(() => {});'); } /** @@ -896,7 +879,7 @@ class behat_app extends behat_base { $this->spin( function() use ($session) { - $session->executeScript($this->islegacy ? 'appRef.tick();' : 'ngZone.run(() => {});'); + $session->executeScript('ngZone.run(() => {});'); $nodes = $this->find_all('css', 'core-loading ion-spinner'); From e1f89c9eab06bcdd7f20916a00bb9e9b668b4425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 24 Nov 2021 10:47:10 +0100 Subject: [PATCH 151/220] MOBILE-3810 behat: Improve get header selector to adapt new titles --- tests/behat/app_behat_runtime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index d26f86651..5c1ff5e84 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -568,7 +568,7 @@ const behatGetHeader = function() { log('Action - Get header'); - let titles = Array.from(document.querySelectorAll('ion-header ion-title, ion-header h1')); + let titles = Array.from(document.querySelectorAll('.ion-page:not(.ion-page-hidden) > ion-header h1')); titles = titles.filter(function(title) { return isElementVisible(title, document.body); }); From 40252a6ed6b52cb0de580fd9516099b7afdb861f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 24 Nov 2021 10:47:10 +0100 Subject: [PATCH 152/220] MOBILE-3810 behat: Change accounts and main menu to user and more menu --- mod/login/tests/behat/app_basic_usage.feature | 6 +++--- tests/behat/app_behat_runtime.js | 5 +++-- tests/behat/behat_app.php | 2 +- tests/behat/navigation_deeplinks.feature | 2 +- tests/behat/navigation_splitview.feature | 10 +++++----- tests/behat/plugins.feature | 4 ++-- 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index c1b1f5747..e985ce73f 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -33,7 +33,7 @@ Feature: Test basic usage of login in app Scenario: Add a non existing account When I enter the app And I log in as "student1" - And I press the accounts menu button in the app + And I press the user menu button in the app And I press "Log out" in the app And I wait the app to restart And I press "Add a new account" in the app @@ -45,7 +45,7 @@ Feature: Test basic usage of login in app Scenario: Add a non existing account from accounts switcher When I enter the app And I log in as "student1" - And I press the accounts menu button in the app + And I press the user menu button in the app And I press "Switch account" in the app And I press "Add a new account" in the app And I wait the app to restart @@ -57,7 +57,7 @@ Feature: Test basic usage of login in app Scenario: Delete an account When I enter the app And I log in as "student1" - And I press the accounts menu button in the app + And I press the user menu button in the app And I press "Log out" in the app And I wait the app to restart Then I should find "Acceptance test site" in the app diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 5c1ff5e84..265704e6a 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -445,13 +445,14 @@ case 'back': foundButton = findElementsBasedOnText({ text: 'Back' })[0]; break; - case 'main menu': + case 'main menu': // Deprecated name. + case 'more menu': foundButton = findElementsBasedOnText({ text: 'More', near: { text: 'Notifications' }, })[0]; break; - case 'accounts menu' : + case 'user menu' : foundButton = findElementsBasedOnText({ text: 'Account' })[0]; break; case 'page menu': diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index b4afc627c..c3c4a0ada 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -536,7 +536,7 @@ class behat_app extends behat_base { /** * Presses standard buttons in the app. * - * @Given /^I press the (back|main menu|page menu|accounts menu) button in the app$/ + * @Given /^I press the (back|more menu|page menu|user menu|main menu) button in the app$/ * @param string $button Button type * @throws DriverException If the button push doesn't work */ diff --git a/tests/behat/navigation_deeplinks.feature b/tests/behat/navigation_deeplinks.feature index 68d1ef148..ef6ac776f 100644 --- a/tests/behat/navigation_deeplinks.feature +++ b/tests/behat/navigation_deeplinks.feature @@ -25,7 +25,7 @@ Feature: It navigates properly using deep links. Scenario: Receive a push notification When I enter the app And I log in as "student2" - And I press the accounts menu button in the app + And I press the user menu button in the app And I press "Log out" in the app And I wait the app to restart And I press "Add a new account" in the app diff --git a/tests/behat/navigation_splitview.feature b/tests/behat/navigation_splitview.feature index 4648b023f..7efe86451 100644 --- a/tests/behat/navigation_splitview.feature +++ b/tests/behat/navigation_splitview.feature @@ -24,10 +24,10 @@ Feature: It navigates properly in pages with a split-view component. Scenario: Navigate in grades tab on mobile - # Open accounts menu + # Open user menu Given I enter the app And I log in as "student1" - And I press the accounts menu button in the app + And I press the user menu button in the app # Open grades page When I press "Grades" in the app @@ -87,11 +87,11 @@ Feature: It navigates properly in pages with a split-view component. Scenario: Navigate in grades tab on tablet - # Open accounts menu + # Open user menu Given I enter the app And I change viewport size to "1200x640" And I log in as "student1" - And I press the accounts menu button in the app + And I press the user menu button in the app # Open grades page When I press "Grades" in the app @@ -137,4 +137,4 @@ Feature: It navigates properly in pages with a split-view component. When I press the back button in the app Then I should find "Acceptance test site" in the app And I should find "Account" in the app - But I should not find "Back" in the app \ No newline at end of file + But I should not find "Back" in the app diff --git a/tests/behat/plugins.feature b/tests/behat/plugins.feature index 501e5a707..35d39f1ca 100644 --- a/tests/behat/plugins.feature +++ b/tests/behat/plugins.feature @@ -6,10 +6,10 @@ Feature: Plugins work properly. | username | | studentusername | - Scenario: See main menu button + Scenario: See more menu button When I enter the app And I log in as "studentusername" - And I press the main menu button in the app + And I press the more menu button in the app Then I should find "Moodle Mobile language strings" in the app When I press "Moodle Mobile language strings" in the app From bff6969d508b136e9f9930a84c6648067b773184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 29 Nov 2021 10:01:55 +0100 Subject: [PATCH 153/220] MOBILE-3806 mainmenu: Fix more menu button search --- tests/behat/app_behat_runtime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 265704e6a..54daed900 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -449,7 +449,7 @@ case 'more menu': foundButton = findElementsBasedOnText({ text: 'More', - near: { text: 'Notifications' }, + near: { text: 'Messages' }, })[0]; break; case 'user menu' : From bc9895dc82a0f67e10e61fea74ca9b2a2bb837f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 29 Nov 2021 10:02:27 +0100 Subject: [PATCH 154/220] MOBILE-3806 core: Remove non supported Moodle versions --- mod/chat/tests/behat/app_basic_usage.feature | 2 +- mod/courses/tests/behat/app_basic_usage.feature | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mod/chat/tests/behat/app_basic_usage.feature b/mod/chat/tests/behat/app_basic_usage.feature index cd3ec9fbf..4a26a9949 100755 --- a/mod/chat/tests/behat/app_basic_usage.feature +++ b/mod/chat/tests/behat/app_basic_usage.feature @@ -57,7 +57,7 @@ Feature: Test basic usage of chat in app And I press "Send" in the app Then I should find "Hi David, I am Pau." in the app - Scenario: Past sessions shown for >=3.5 + Scenario: Past sessions shown # Send messages as student1 Given I enter the app And I log in as "student1" diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index 0bb029c26..5f3ead46c 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -34,7 +34,7 @@ Feature: Test basic usage of courses in app | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | | assign | C1 | assign1 | assignment | Test assignment description | 1 | - Scenario: "Dashboard" tab displayed in >= 3.3 sites + Scenario: "Dashboard" tab displayed When I enter the app And I log in as "student1" Then I should see "Dashboard" From 1c59cd27002a22c14a568ef6cdb0a6593eb55fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 29 Nov 2021 10:04:21 +0100 Subject: [PATCH 155/220] MOBILE-3806 courseoverview: Fix filter courses --- mod/course/tests/behat/app_courselist.feature | 7 +------ tests/behat/behat_app.php | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/mod/course/tests/behat/app_courselist.feature b/mod/course/tests/behat/app_courselist.feature index fc8adab44..08788755d 100644 --- a/mod/course/tests/behat/app_courselist.feature +++ b/mod/course/tests/behat/app_courselist.feature @@ -91,10 +91,6 @@ Feature: Test course list shown on app start tab And I should find "Course 5" in the app And I should find "Toad 6" in the app - When I press "Display options" near "Course overview" in the app - And I press "Filter my courses" in the app - - # TODO field should be "Filter my courses" And I set the field "search text" to "fr" in the app Then I should find "C3" in the app @@ -110,8 +106,7 @@ Feature: Test course list shown on app start tab And I should not find "Course 5" in the app And I should not find "Toad 6" in the app - When I press "Display options" near "Course overview" in the app - And I press "Filter my courses" in the app + When I set the field "search text" to "" in the app Then I should find "C1" in the app And I should find "C2" in the app And I should find "C3" in the app diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index c3c4a0ada..87c23602c 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -733,7 +733,7 @@ class behat_app extends behat_base { * Currently this only works for input fields which must be identified using a partial or * exact match on the placeholder text. * - * @Given /^I set the field "((?:[^"]|\\")+)" to "((?:[^"]|\\")+)" in the app$/ + * @Given /^I set the field "((?:[^"]|\\")+)" to "((?:[^"]|\\")*)" in the app$/ * @param string $field Text identifying field * @param string $value Value for field * @throws DriverException If the field set doesn't work From fd07b4169609173808250c0c50bc43263776dd9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 29 Nov 2021 10:37:04 +0100 Subject: [PATCH 156/220] MOBILE-3806 courses: Use My courses tab to access courses --- .../tests/behat/app_basic_usage.feature | 16 +++++----- mod/chat/tests/behat/app_basic_usage.feature | 8 ++--- .../tests/behat/app_basic_usage.feature | 14 ++++----- .../tests/behat/app_basic_usage.feature | 24 +++++++-------- .../tests/behat/app_basic_usage.feature | 14 ++++----- .../tests/behat/app_course_completion.feature | 2 +- .../tests/behat/app_basic_usage.feature | 8 ++--- mod/data/tests/behat/app_data_entries.feature | 16 +++++----- mod/data/tests/behat/app_data_sync.feature | 6 ++-- mod/forum/tests/behat/app_basic_usage.feature | 30 +++++++++---------- .../tests/behat/app_basic_usage.feature | 26 ++++++++-------- .../tests/behat/app_basic_usage.feature | 10 +++---- mod/quiz/tests/behat/app_basic_usage.feature | 8 ++--- .../tests/behat/app_quiz_navigation.feature | 2 +- .../tests/behat/app_basic_usage.feature | 14 ++++----- tests/behat/behat_app.php | 28 +++++++++++++++++ tests/behat/navigation_activities.feature | 2 +- tests/behat/navigation_externallinks.feature | 2 +- tests/behat/navigation_gestures.feature | 4 +-- 19 files changed, 131 insertions(+), 103 deletions(-) diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index 722ef7cec..1c4fd025d 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -23,7 +23,7 @@ Feature: Test basic usage of assignment activity in app # Create, edit and submit as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "assignment1" in the app Then the header should be "assignment1" in the app And I should find "Test assignment description1" in the app @@ -51,7 +51,7 @@ Feature: Test basic usage of assignment activity in app # View as a teacher When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "assignment1" in the app Then the header should be "assignment1" in the app @@ -67,7 +67,7 @@ Feature: Test basic usage of assignment activity in app # Submit first attempt as a student Given I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "assignment1" in the app And I press "Add submission" in the app And I set the field "Online text submissions" to "Submission test 1st attempt" in the app @@ -78,7 +78,7 @@ Feature: Test basic usage of assignment activity in app # Allow more attempts as a teacher When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "assignment1" in the app And I press "Participants" in the app And I press "Student student" near "assignment1" in the app @@ -91,7 +91,7 @@ Feature: Test basic usage of assignment activity in app # Submit second attempt as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "assignment1" in the app Then I should find "Reopened" in the app And I should find "2 out of Unlimited" in the app @@ -111,7 +111,7 @@ Feature: Test basic usage of assignment activity in app # View second attempt as a teacher When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "assignment1" in the app And I press "Participants" in the app And I press "Student student" near "assignment1" in the app @@ -121,7 +121,7 @@ Feature: Test basic usage of assignment activity in app Scenario: Add submission offline (online text) & Submit for grading offline & Sync submissions When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "assignment1" in the app And I press "Add submission" in the app And I switch offline mode to "true" @@ -142,7 +142,7 @@ Feature: Test basic usage of assignment activity in app Scenario: Edit an offline submission before synchronising it When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "assignment1" in the app And I press "Add submission" in the app And I switch offline mode to "true" diff --git a/mod/chat/tests/behat/app_basic_usage.feature b/mod/chat/tests/behat/app_basic_usage.feature index 4a26a9949..3a09d3c86 100755 --- a/mod/chat/tests/behat/app_basic_usage.feature +++ b/mod/chat/tests/behat/app_basic_usage.feature @@ -23,7 +23,7 @@ Feature: Test basic usage of chat in app # Send messages as student1 When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test chat name" in the app Then I should find "Click here to enter the chat now" in the app And I should find "View past chat sessions" in the app @@ -41,7 +41,7 @@ Feature: Test basic usage of chat in app # Read messages, view connected users, send beep and reply as student2 When I enter the app And I log in as "student2" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test chat name" in the app And I press "Click here to enter the chat now" in the app Then I should find "Hi!" in the app @@ -61,7 +61,7 @@ Feature: Test basic usage of chat in app # Send messages as student1 Given I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test chat name" in the app And I press "Click here to enter the chat now" in the app And I set the field "New message" to "Hi!" in the app @@ -75,7 +75,7 @@ Feature: Test basic usage of chat in app # Read messages from past sessions as student2 When I enter the app And I log in as "student2" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test chat name" in the app And I press "View past chat sessions" in the app And I press "Show incomplete sessions" in the app diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 98819e5d2..00622c74d 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -23,7 +23,7 @@ Feature: Test basic usage of choice activity in app | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test single choice name" in the app And I select "Option 1" in the app And I select "Option 2" in the app @@ -48,7 +48,7 @@ Feature: Test basic usage of choice activity in app | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test multi choice name" in the app And I select "Option 1" in the app And I select "Option 2" in the app @@ -78,7 +78,7 @@ Feature: Test basic usage of choice activity in app | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test single choice name" in the app And I select "Option 1" in the app And I switch offline mode to "true" @@ -112,7 +112,7 @@ Feature: Test basic usage of choice activity in app | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test single choice name" in the app And I select "Option 1" in the app And I switch offline mode to "true" @@ -141,7 +141,7 @@ Feature: Test basic usage of choice activity in app | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Display options" in the app And I press "Show download options" in the app And I press "Download" near "Test single choice name" in the app @@ -182,7 +182,7 @@ Feature: Test basic usage of choice activity in app | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | And I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Choice name" in the app And I select "Option 2" in the app And I press "Save my choice" in the app @@ -191,7 +191,7 @@ Feature: Test basic usage of choice activity in app # Download answers as teacher When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Choice name" in the app Then I should find "Test choice description" in the app diff --git a/mod/comments/tests/behat/app_basic_usage.feature b/mod/comments/tests/behat/app_basic_usage.feature index b8036aa17..9064d47ab 100755 --- a/mod/comments/tests/behat/app_basic_usage.feature +++ b/mod/comments/tests/behat/app_basic_usage.feature @@ -28,7 +28,7 @@ Feature: Test basic usage of comments in app # Create database entry and comment as a teacher Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Data" in the app And I press "Display options" in the app And I press "Open in browser" in the app @@ -41,7 +41,7 @@ Feature: Test basic usage of comments in app And I close the browser tab opened by the app When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Data" in the app And I press "add" in the app And I set the field "Test field name" to "Test" in the app @@ -60,7 +60,7 @@ Feature: Test basic usage of comments in app # Create and delete comments as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Data" in the app And I press "More" in the app And I press "Comments (1)" in the app @@ -87,7 +87,7 @@ Feature: Test basic usage of comments in app Scenario: Add comments offline & Delete comments offline & Sync comments (database) Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Data" in the app And I press "Display options" in the app And I press "Open in browser" in the app @@ -100,7 +100,7 @@ Feature: Test basic usage of comments in app And I close the browser tab opened by the app When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Data" in the app And I press "add" in the app And I set the field "Test field name" to "Test" in the app @@ -150,7 +150,7 @@ Feature: Test basic usage of comments in app # Create glossary entry and comment as a teacher When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -169,7 +169,7 @@ Feature: Test basic usage of comments in app # Create and delete comments as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "potato" in the app And I press "Comments (1)" in the app @@ -196,7 +196,7 @@ Feature: Test basic usage of comments in app Scenario: Add comments offline & Delete comments offline & Sync comments (glossary) When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -247,7 +247,7 @@ Feature: Test basic usage of comments in app # Create blog as a teacher Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "menu" in the app And I press "Website" in the app And I switch to the browser tab opened by the app @@ -268,7 +268,7 @@ Feature: Test basic usage of comments in app # Create and delete comments as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "menu" in the app And I press "Site blog" in the app Then I should see "Blog test" @@ -297,7 +297,7 @@ Feature: Test basic usage of comments in app # Create blog as a teacher Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "menu" in the app And I press "Website" in the app And I switch to the browser tab opened by the app @@ -318,7 +318,7 @@ Feature: Test basic usage of comments in app # Create and delete comments as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "menu" in the app And I press "Site blog" in the app Then I should see "Blog test" diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 7fe904f2c..f752dd799 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -74,7 +74,7 @@ Feature: Test basic usage of one course in app Scenario: View course contents When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -151,7 +151,7 @@ Feature: Test basic usage of one course in app Scenario: View section contents When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -330,7 +330,7 @@ Feature: Test basic usage of one course in app Scenario: Navigation between sections using the bottom arrows When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -409,7 +409,7 @@ Feature: Test basic usage of one course in app Scenario: Self enrol Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app @@ -449,7 +449,7 @@ Feature: Test basic usage of one course in app Scenario: Guest access Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app @@ -489,7 +489,7 @@ Feature: Test basic usage of one course in app Scenario: View blocks on drawer Given I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app @@ -511,7 +511,7 @@ Feature: Test basic usage of one course in app And I close the browser tab opened by the app When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app diff --git a/mod/course/tests/behat/app_course_completion.feature b/mod/course/tests/behat/app_course_completion.feature index 129f56c79..52a23b979 100644 --- a/mod/course/tests/behat/app_course_completion.feature +++ b/mod/course/tests/behat/app_course_completion.feature @@ -22,7 +22,7 @@ Feature: Check course completion feature. | forum | Second forum | C1 | forum2 | 1 | 0 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app # Set activities as completed. And I should find "0%" in the app And I press "Mark First forum as done" in the app diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index 5f3ead46c..bed2e812a 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -60,7 +60,7 @@ Feature: Test basic usage of courses in app And I should find "Course 2" in the app And I should find "Course 3" in the app - When I press "Course 1" near "Course overview" in the app + When I press "Course 1" in the app Then I should find "Choice course 1" in the app And the header should be "Course 1" in the app @@ -70,12 +70,12 @@ Feature: Test basic usage of courses in app When I press the back button in the app And I press the back button in the app - And I press "Course 2" near "Course overview" in the app + And I press "Course 2" in the app Then I should find "Choice course 2" in the app And the header should be "Course 2" in the app When I press the back button in the app - And I press "Course 3" near "Course overview" in the app + And I press "Course 3" in the app Then I should find "Choice course 3" in the app And the header should be "Course 3" in the app @@ -108,7 +108,7 @@ Feature: Test basic usage of courses in app Then I press "Open block drawer" in the app Then I should find "Timeline" in the app - Given I press "Course 1" near "Course overview" in the app + Given I press "Course 1" in the app And I press "assignment" in the app And I press "Display options" in the app And I press "Open in browser" in the app diff --git a/mod/data/tests/behat/app_data_entries.feature b/mod/data/tests/behat/app_data_entries.feature index 5fb346918..dd8c5621b 100644 --- a/mod/data/tests/behat/app_data_entries.feature +++ b/mod/data/tests/behat/app_data_entries.feature @@ -34,7 +34,7 @@ Feature: Users can manage entries in database activities Scenario: Create entry Given I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Web links" near "General" in the app And I should see "No entries in database" When I press "Add entries" in the app @@ -47,7 +47,7 @@ Feature: Users can manage entries in database activities Scenario: Browse entry Given I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Web links" near "General" in the app And I press "Add entries" in the app And I set the field "URL" to "https://moodle.org/" in the app @@ -55,7 +55,7 @@ Feature: Users can manage entries in database activities And I press "Save" near "Web links" in the app When I enter the app And I log in as "student2" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Web links" near "General" in the app And I press "Add entries" in the app And I set the field "URL" to "https://moodlecloud.com/" in the app @@ -79,7 +79,7 @@ Feature: Users can manage entries in database activities Scenario: Students can not edit or delete other user's entries from list and single view in the app Given I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Web links" near "General" in the app And I press "Add entries" in the app And I set the field "URL" to "https://moodle.org/" in the app @@ -87,7 +87,7 @@ Feature: Users can manage entries in database activities And I press "Save" near "Web links" in the app When I enter the app And I log in as "student2" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Web links" near "General" in the app Then "Edit" "link" should not exist And "Delete" "link" should not exist @@ -98,7 +98,7 @@ Feature: Users can manage entries in database activities Scenario: Delete entry (student) & Update entry (student) Given I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Web links" near "General" in the app And I press "Add entries" in the app And I set the field "URL" to "https://moodle.org/" in the app @@ -146,7 +146,7 @@ Feature: Users can manage entries in database activities Scenario: Delete entry (teacher) & Update entry (teacher) Given I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Web links" near "General" in the app And I press "Add entries" in the app And I set the field "URL" to "https://moodle.org/" in the app @@ -158,7 +158,7 @@ Feature: Users can manage entries in database activities And I press "Save" near "Web links" in the app When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Web links" near "General" in the app Then I should see "https://moodle.org/" And I should see "Moodle community site" diff --git a/mod/data/tests/behat/app_data_sync.feature b/mod/data/tests/behat/app_data_sync.feature index 065ffe35f..ff9b47a4f 100644 --- a/mod/data/tests/behat/app_data_sync.feature +++ b/mod/data/tests/behat/app_data_sync.feature @@ -35,7 +35,7 @@ Feature: Users can store entries in database activities when offline and sync wh Scenario: Create entry (offline) Given I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Web links" near "General" in the app And I switch offline mode to "true" And I should see "No entries in database" @@ -57,7 +57,7 @@ Feature: Users can store entries in database activities when offline and sync wh Scenario: Update entry (offline) & Delete entry (offline) Given I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Web links" near "General" in the app And I should see "No entries in database" And I press "Add entries" in the app @@ -108,7 +108,7 @@ Feature: Users can store entries in database activities when offline and sync wh Scenario: Students can undo deleting entries to a database in the app while offline Given I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Web links" near "General" in the app And I should see "No entries in database" And I press "Add entries" in the app diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index b2cb3d8ac..c9c5ad14e 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -27,7 +27,7 @@ Feature: Test basic usage of forum activity in app Scenario: Create new discussion When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "My happy subject" in the app @@ -41,7 +41,7 @@ Feature: Test basic usage of forum activity in app Scenario: Reply a post When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app @@ -59,7 +59,7 @@ Feature: Test basic usage of forum activity in app Scenario: Star and pin discussions (student) When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "starred subject" in the app @@ -95,7 +95,7 @@ Feature: Test basic usage of forum activity in app Scenario: Star and pin discussions (teacher) When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test star" in the app @@ -127,7 +127,7 @@ Feature: Test basic usage of forum activity in app Scenario: Edit a not sent reply offline When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app @@ -162,7 +162,7 @@ Feature: Test basic usage of forum activity in app Scenario: Edit a not sent new discussion offline When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I switch offline mode to "true" And I press "Add a new discussion topic" in the app @@ -187,7 +187,7 @@ Feature: Test basic usage of forum activity in app Scenario: Edit a forum post (only online) When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app @@ -215,7 +215,7 @@ Feature: Test basic usage of forum activity in app Scenario: Delete a forum post (only online) When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app @@ -249,7 +249,7 @@ Feature: Test basic usage of forum activity in app Scenario: Add/view ratings Given I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app @@ -263,7 +263,7 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Auto-test" in the app Then I should find "Reply" in the app @@ -292,7 +292,7 @@ Feature: Test basic usage of forum activity in app When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Auto-test" in the app Then I should find "Average of ratings: 1" in the app @@ -302,7 +302,7 @@ Feature: Test basic usage of forum activity in app Scenario: Reply a post offline When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app @@ -334,7 +334,7 @@ Feature: Test basic usage of forum activity in app Scenario: New discussion offline & Sync Forum When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I switch offline mode to "true" And I press "Add a new discussion topic" in the app @@ -359,7 +359,7 @@ Feature: Test basic usage of forum activity in app Scenario: New discussion offline & Auto-sync forum When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I switch offline mode to "true" And I press "Add a new discussion topic" in the app @@ -384,7 +384,7 @@ Feature: Test basic usage of forum activity in app Scenario: Prefetch When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "DiscussionSubject 1" in the app diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index 169345a26..fee4f409d 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -29,7 +29,7 @@ Feature: Test basic usage of glossary in app Scenario: View a glossary and its terms When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -56,7 +56,7 @@ Feature: Test basic usage of glossary in app Scenario: Change filters (include search) When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -94,7 +94,7 @@ Feature: Test basic usage of glossary in app When the "glossary" filter is "on" And I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -139,7 +139,7 @@ Feature: Test basic usage of glossary in app # Create entries as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -164,7 +164,7 @@ Feature: Test basic usage of glossary in app # Write comments as a teacher When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then I should see "Comments (0)" @@ -186,7 +186,7 @@ Feature: Test basic usage of glossary in app # View comments as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then I should see "Comments (2)" @@ -199,7 +199,7 @@ Feature: Test basic usage of glossary in app Scenario: Prefetch When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -222,7 +222,7 @@ Feature: Test basic usage of glossary in app And I press "Download" in the app And I press the back button in the app And I press the back button in the app - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I switch offline mode to "true" And I press "Test glossary" in the app Then the header should be "Test glossary" in the app @@ -240,7 +240,7 @@ Feature: Test basic usage of glossary in app Scenario: Sync When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I switch offline mode to "true" And I press "close" in the app @@ -282,7 +282,7 @@ Feature: Test basic usage of glossary in app # Create entries as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -304,7 +304,7 @@ Feature: Test basic usage of glossary in app # Rate entries as teacher1 When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then I should see "Average of ratings: -" @@ -316,7 +316,7 @@ Feature: Test basic usage of glossary in app # Rate entries as teacher2 When I enter the app And I log in as "teacher2" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "mountain" in the app And I switch offline mode to "true" @@ -337,7 +337,7 @@ Feature: Test basic usage of glossary in app # View ratings as a student When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then the header should be "mountain" in the app diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index a03944489..7af987d3f 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -292,7 +292,7 @@ Feature: Test basic usage of messages in app Scenario: User blocking feature When I enter the app And I log in as "student2" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Participants" in the app And I press "Student1 student1" in the app And I press "Message" in the app @@ -303,7 +303,7 @@ Feature: Test basic usage of messages in app When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app @@ -311,7 +311,7 @@ Feature: Test basic usage of messages in app When I enter the app And I log in as "student2" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Participants" in the app And I press "Student1 student1" in the app And I press "Message" in the app @@ -325,7 +325,7 @@ Feature: Test basic usage of messages in app When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app @@ -337,7 +337,7 @@ Feature: Test basic usage of messages in app Scenario: Mute Unmute conversations When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app diff --git a/mod/quiz/tests/behat/app_basic_usage.feature b/mod/quiz/tests/behat/app_basic_usage.feature index d03e3c9db..ead2f1454 100755 --- a/mod/quiz/tests/behat/app_basic_usage.feature +++ b/mod/quiz/tests/behat/app_basic_usage.feature @@ -58,7 +58,7 @@ Feature: Attempt a quiz in app Scenario: View a quiz entry page (attempts, status, etc.) When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Quiz 1" in the app And I press "Attempt quiz now" in the app Then I should find "Text of the first question" in the app @@ -110,7 +110,7 @@ Feature: Attempt a quiz in app Scenario: Attempt a quiz (all question types) When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Quiz 2" in the app And I press "Attempt quiz now" in the app And I press "Four" in the app @@ -149,7 +149,7 @@ Feature: Attempt a quiz in app Scenario: Submit a quiz & Review a quiz attempt When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Quiz 1" in the app And I press "Attempt quiz now" in the app And I press "True" in the app @@ -162,7 +162,7 @@ Feature: Attempt a quiz in app When I enter the app And I log in as "teacher1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Quiz 1" in the app And I press "Display options" in the app And I press "Open in browser" in the app diff --git a/mod/quiz/tests/behat/app_quiz_navigation.feature b/mod/quiz/tests/behat/app_quiz_navigation.feature index acf59c360..6cd114a3b 100644 --- a/mod/quiz/tests/behat/app_quiz_navigation.feature +++ b/mod/quiz/tests/behat/app_quiz_navigation.feature @@ -32,7 +32,7 @@ Feature: Attempt a quiz in app Scenario: Next and previous navigation Given I enter the app And I log in as "student1" - When I press "Course 1" near "Course overview" in the app + When I enter the course "Course 1" in the app And I press "Quiz 1" in the app And I press "Attempt quiz now" in the app Then I should find "Text of the first question" in the app diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index fcba1840e..4a0004b43 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -24,7 +24,7 @@ Feature: Test basic usage of survey activity in app Scenario: Answer a survey & View results (ATTLS) When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test survey name" in the app And I press "Choose" near "1. In evaluating what someone says, I focus on the quality of their argument, not on the person who's presenting it." in the app And I press "Strongly agree" in the app @@ -81,7 +81,7 @@ Feature: Test basic usage of survey activity in app | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test survey critical incidents" in the app And I set the field with xpath "//textarea[@aria-label='At what moment in class were you most engaged as a learner?']" to "1st answer" And I set the field with xpath "//textarea[@aria-label='At what moment in class were you most distanced as a learner?']" to "2nd answer" @@ -109,7 +109,7 @@ Feature: Test basic usage of survey activity in app | survey | Test survey Colles (actual) | Test survey1 | 1 | C1 | survey1 | 0 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test survey Colles (actual)" in the app And I press "Choose" near "1. my learning focuses on issues that interest me." in the app And I press "Sometimes" near "Often" in the app @@ -178,7 +178,7 @@ Feature: Test basic usage of survey activity in app | survey | Test survey Colles (preferred) | Test survey1 | 2 | C1 | survey1 | 0 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test survey Colles (preferred)" in the app And I press "Choose" near "1. my learning focuses on issues that interest me." in the app And I press "Sometimes" near "Often" in the app @@ -247,7 +247,7 @@ Feature: Test basic usage of survey activity in app | survey | Test survey Colles (preferred and actual) | Test survey1 | 3 | C1 | survey1 | 0 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test survey Colles (preferred and actual)" in the app And I press "Choose" near "1. I prefer that my learning focuses on issues that interest me." in the app And I press "Sometimes" near "Often" in the app @@ -364,7 +364,7 @@ Feature: Test basic usage of survey activity in app | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test survey critical incidents" in the app And I switch offline mode to "true" And I press "Submit" in the app @@ -387,7 +387,7 @@ Feature: Test basic usage of survey activity in app | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test survey critical incidents" in the app diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 87c23602c..fb7fd3937 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -533,6 +533,34 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } + /** + * User enters a course in the app. + * + * @Given /^I enter the course "(.+)" in the app$/ + * @param string $coursename Course name + * @throws DriverException If the button push doesn't work + */ + public function i_enter_the_course_in_the_app(string $coursename) { + try { + $this->i_press_in_the_app('"My courses" near "Messages"'); + } catch (DriverException $e) { + // My courses not present enter from Dashboard. + $this->i_press_in_the_app('"Home" near "Messages"'); + $this->i_press_in_the_app('"Dashboard"'); + $this->i_press_in_the_app('"'.$coursename.'" near "Course overview"'); + + $this->wait_for_pending_js(); + + return true; + } + + $this->i_press_in_the_app('"'.$coursename.'"'); + + $this->wait_for_pending_js(); + + return true; + } + /** * Presses standard buttons in the app. * diff --git a/tests/behat/navigation_activities.feature b/tests/behat/navigation_activities.feature index 210b8293e..a11144da3 100644 --- a/tests/behat/navigation_activities.feature +++ b/tests/behat/navigation_activities.feature @@ -20,7 +20,7 @@ Feature: It navigates properly within activities. Scenario: Navigates using deep links When I enter the app And I log in as "student" - And I press "Course 1" in the app + And I enter the course "Course 1" in the app And I press "Page" in the app And I press "Go to label" in the app Then I should find "Label description" in the app diff --git a/tests/behat/navigation_externallinks.feature b/tests/behat/navigation_externallinks.feature index b3da3c3be..1be8c2d91 100644 --- a/tests/behat/navigation_externallinks.feature +++ b/tests/behat/navigation_externallinks.feature @@ -21,7 +21,7 @@ Feature: It opens external links properly. Scenario: Click an external link When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Test forum" in the app And I press "Forum topic" in the app And I press "moodle.org" in the app diff --git a/tests/behat/navigation_gestures.feature b/tests/behat/navigation_gestures.feature index e51465d27..8e83275fe 100644 --- a/tests/behat/navigation_gestures.feature +++ b/tests/behat/navigation_gestures.feature @@ -23,7 +23,7 @@ Feature: It navigates using gestures. Scenario: Swipe between participants When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Participants" in the app And I press "Student First" in the app And I swipe to the left in the app @@ -44,7 +44,7 @@ Feature: It navigates using gestures. Scenario: Swipe between filtered participants When I enter the app And I log in as "student1" - And I press "Course 1" near "Course overview" in the app + And I enter the course "Course 1" in the app And I press "Participants" in the app And I press "Search" in the app And I set the field "Search" to "student" in the app From 82bf7b4b22e4d7d77f347f229fbb93fd9061af3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 29 Nov 2021 10:37:41 +0100 Subject: [PATCH 157/220] MOBILE-3806 courses: Use Course overview from my courses --- mod/course/tests/behat/app_courselist.feature | 3 +++ mod/courses/tests/behat/app_basic_usage.feature | 10 ++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/mod/course/tests/behat/app_courselist.feature b/mod/course/tests/behat/app_courselist.feature index 08788755d..7619ec85e 100644 --- a/mod/course/tests/behat/app_courselist.feature +++ b/mod/course/tests/behat/app_courselist.feature @@ -22,6 +22,7 @@ Feature: Test course list shown on app start tab Scenario: View courses (shortnames not displayed) When I enter the app And I log in as "student1" + And I press "My courses" in the app Then I should find "Course 1" in the app But I should not find "Course 2" in the app But I should not find "C1" in the app @@ -29,6 +30,7 @@ Feature: Test course list shown on app start tab When I enter the app And I log in as "student2" + And I press "My courses" in the app Then I should find "Course 1" in the app And I should find "Course 2" in the app But I should not find "C1" in the app @@ -78,6 +80,7 @@ Feature: Test course list shown on app start tab | student2 | Z10 | student | When I enter the app And I log in as "student2" + And I press "My courses" in the app Then I should find "C1" in the app And I should find "C2" in the app And I should find "C3" in the app diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index bed2e812a..7dc6932ef 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -39,15 +39,12 @@ Feature: Test basic usage of courses in app And I log in as "student1" Then I should see "Dashboard" And the header should be "Acceptance test site" in the app - And I should find "Course 1" in the app - And I should find "Course 2" in the app - And I should find "Course 3" in the app - - When I press "Site home" in the app + And I should see "Timeline" + And I press "Site home" in the app Then I should find "Dashboard" in the app And the header should be "Acceptance test site" in the app - When I press "Dashboard" in the app + When I press "My courses" in the app Then I should find "Course 1" in the app And I should find "Course 2" in the app And I should find "Course 3" in the app @@ -56,6 +53,7 @@ Feature: Test basic usage of courses in app When I enter the app And I log in as "student1" Then the header should be "Acceptance test site" in the app + And I press "My courses" in the app And I should find "Course 1" in the app And I should find "Course 2" in the app And I should find "Course 3" in the app From e9266ad9fd5050d6c8261229c1505f95d789e166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 29 Nov 2021 12:22:32 +0100 Subject: [PATCH 158/220] MOBILE-3806 blocks: Fix open/close block drawer --- mod/course/tests/behat/app_basic_usage.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index f752dd799..d9e26d457 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -499,10 +499,10 @@ Feature: Test basic usage of one course in app And I click on "Side panel" "button" And I follow "Add a block" And I follow "Text" - And I click on "#theme_boost-drawers-blocks [aria-label=\"Close drawer\"]" "css_element" And I click on "Side panel" "button" And I follow "Add a block" And I follow "Activities" + And I click on "Open block drawer" "button" And I click on "Actions menu" "icon" in the "#action-menu-toggle-0" "css_element" And I follow "Configure (new text block) block" And I set the field "Text block title" to "HTML title test" From 9724088a872b981b2bd63d18cb41b9e0a9a3b14b Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 1 Dec 2021 14:24:43 +0100 Subject: [PATCH 159/220] MOBILE-3926 behat: Add split-view scoping to find --- tests/behat/app_behat_runtime.js | 26 +++++++++++++++++--------- tests/behat/behat_app.php | 10 ++++++---- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 54daed900..4d0c9a940 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -349,10 +349,16 @@ * Function to find elements based on their text or Aria label. * * @param {object} locator Element locator. + * @param {boolean} insideSplitView Whether to search only inside the split view contents. * @return {HTMLElement} Found elements */ - const findElementsBasedOnText = function(locator) { - const topContainer = document.querySelector('ion-alert, ion-popover, ion-action-sheet, core-ion-tab.show-tab ion-page.show-page, ion-page.show-page, html'); + const findElementsBasedOnText = function(locator, insideSplitView) { + let topContainer = document.querySelector('ion-alert, ion-popover, ion-action-sheet, core-ion-tab.show-tab ion-page.show-page, ion-page.show-page, html'); + + if (insideSplitView) { + topContainer = topContainer.querySelector('core-split-view ion-router-outlet'); + } + let container = topContainer; if (topContainer && locator.near) { @@ -382,7 +388,7 @@ if (filteredElements.length > 0) { return filteredElements; } - } while ((container = getParentElement(container)) && container !== topContainer); + } while (container !== topContainer && (container = getParentElement(container)) && container !== topContainer); return []; }; @@ -497,21 +503,23 @@ }; /** - * Function to find an arbitrary item based on its text or aria label. + * Function to find an arbitrary element based on its text or aria label. * * @param {object} locator Element locator. + * @param {boolean} insideSplitView Whether to search only inside the split view contents. * @return {string} OK if successful, or ERROR: followed by message */ - const behatFind = function(locator) { - log('Action - Find', locator); + const behatFind = function(locator, insideSplitView) { + log('Action - Find', { locator, insideSplitView }); try { - const element = findElementsBasedOnText(locator)[0]; + const element = findElementsBasedOnText(locator, insideSplitView)[0]; if (!element) { return 'ERROR: No matches for text'; } + log('Action - Found', { locator, insideSplitView, element }); return 'OK'; } catch (error) { return 'ERROR: ' + error.message; @@ -573,7 +581,6 @@ titles = titles.filter(function(title) { return isElementVisible(title, document.body); }); - if (titles.length > 1) { return 'ERROR: Too many possible titles'; @@ -597,7 +604,6 @@ const behatSetField = function(field, value) { log('Action - Set field ' + field + ' to: ' + value); - const found = findElementsBasedOnText({ text: field, selector: 'input, textarea, [contenteditable="true"]' })[0]; if (!found) { return 'ERROR: No matches for text'; @@ -656,6 +662,8 @@ * @return {object} Component instance */ const behatGetComponentInstance = function(selector, className) { + log('Action - Get component instance ' + selector + ', ' + className); + const activeElement = Array.from(document.querySelectorAll(`.ion-page:not(.ion-page-hidden) ${selector}`)).pop(); if (!activeElement || !activeElement.__ngContext__) { diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index fb7fd3937..2386f1b2a 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -154,16 +154,18 @@ class behat_app extends behat_base { /** * Finds elements in the app. * - * @Then /^I should( not)? find (".+") in the app$/ + * @Then /^I should( not)? find (".+")( inside the split-view content)? in the app$/ * @param bool $not * @param string $locator + * @param bool $insidesplitview */ - public function i_find_in_the_app(bool $not, string $locator) { + public function i_find_in_the_app(bool $not, string $locator, bool $insidesplitview = false) { $locator = $this->parse_element_locator($locator); $locatorjson = json_encode($locator); + $insidesplitviewjson = json_encode($insidesplitview); - $this->spin(function() use ($not, $locatorjson) { - $result = $this->evaluate_script("return window.behat.find($locatorjson);"); + $this->spin(function() use ($not, $locatorjson, $insidesplitviewjson) { + $result = $this->evaluate_script("return window.behat.find($locatorjson, $insidesplitviewjson);"); if ($not && $result === 'OK') { throw new DriverException('Error, found an item that should not be found'); From 89488bd71a9bcdd1c6386c8f3b04bfc96e990809 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 25 Nov 2021 13:04:25 +0100 Subject: [PATCH 160/220] MOBILE-3926 behat: Implement scroll to step --- tests/behat/app_behat_runtime.js | 28 ++++++++++++++++++++++++++++ tests/behat/behat_app.php | 23 +++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 4d0c9a940..937142cec 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -526,6 +526,33 @@ } }; + /** + * Scroll an element into view. + * + * @param {object} locator Element locator. + * @return {string} OK if successful, or ERROR: followed by message + */ + const behatScrollTo = function(locator) { + log('Action - scrollTo', { locator }); + + try { + let element = findElementsBasedOnText(locator)[0]; + + if (!element) { + return 'ERROR: No matches for text'; + } + + element = element.closest('ion-item') ?? element.closest('button') ?? element; + + element.scrollIntoView(); + + log('Action - Scrolled to', { locator, element }); + return 'OK'; + } catch (error) { + return 'ERROR: ' + error.message; + } + } + /** * Check whether an item is selected or not. * @@ -678,6 +705,7 @@ pressStandard : behatPressStandard, closePopup : behatClosePopup, find : behatFind, + scrollTo : behatScrollTo, isSelected : behatIsSelected, press : behatPress, setField : behatSetField, diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 2386f1b2a..67d5ab2ef 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -181,6 +181,29 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } + /** + * Scroll to an element in the app. + * + * @When /^I scroll to (".+") in the app$/ + * @param string $locator + */ + public function i_scroll_to_in_the_app(string $locator) { + $locator = $this->parse_element_locator($locator); + $locatorjson = json_encode($locator); + + $this->spin(function() use ($locatorjson) { + $result = $this->evaluate_script("return window.behat.scrollTo($locatorjson);"); + + if ($result !== 'OK') { + throw new DriverException('Error finding item - ' . $result); + } + + return true; + }); + + $this->wait_for_pending_js(); + } + /** * Trigger swipe gesture. * From 771b4039e691451e491f9030c603abf3a1af8149 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 1 Dec 2021 14:12:15 +0100 Subject: [PATCH 161/220] MOBILE-3926 behat: Implement load items step --- tests/behat/app_behat_runtime.js | 47 +++++++++++++++++++++++++++ tests/behat/behat_app.php | 56 ++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 937142cec..a9c3df3cf 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -553,6 +553,52 @@ } } + /** + * Load more items form an active list with infinite loader. + * + * @return {string} OK if successful, or ERROR: followed by message + */ + const behatLoadMoreItems = async function() { + log('Action - loadMoreItems'); + + try { + const infiniteLoading = Array + .from(document.querySelectorAll('core-infinite-loading')) + .find(element => !element.closest('.ion-page-hidden')); + + if (!infiniteLoading) { + return 'ERROR: There isn\'t an infinite loader in the current page'; + } + + const initialOffset = infiniteLoading.offsetTop; + const isLoading = () => !!infiniteLoading.querySelector('ion-spinner[aria-label]'); + const isCompleted = () => !isLoading() && !infiniteLoading.querySelector('ion-button'); + const hasMoved = () => infiniteLoading.offsetTop !== initialOffset; + + if (isCompleted()) { + return 'ERROR: All items are already loaded'; + } + + infiniteLoading.scrollIntoView(); + + // Wait 100ms + await new Promise(resolve => setTimeout(resolve, 100)); + + if (isLoading() || isCompleted() || hasMoved()) { + return 'OK'; + } + + infiniteLoading.querySelector('ion-button').click(); + + // Wait 100ms + await new Promise(resolve => setTimeout(resolve, 100)); + + return (isLoading() || isCompleted() || hasMoved()) ? 'OK' : 'ERROR: Couldn\'t load more items'; + } catch (error) { + return 'ERROR: ' + error.message; + } + } + /** * Check whether an item is selected or not. * @@ -706,6 +752,7 @@ closePopup : behatClosePopup, find : behatFind, scrollTo : behatScrollTo, + loadMoreItems: behatLoadMoreItems, isSelected : behatIsSelected, press : behatPress, setField : behatSetField, diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 67d5ab2ef..c7f8b193d 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -204,6 +204,30 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } + /** + * Load more items in a list with an infinite loader. + * + * @When /^I (should not be able to )?load more items in the app$/ + * @param bool $not + */ + public function i_load_more_items_in_the_app(bool $not = false) { + $this->spin(function() use ($not) { + $result = $this->evaluate_async_script('return window.behat.loadMoreItems();'); + + if ($not && $result !== 'ERROR: All items are already loaded') { + throw new DriverException('It should not have been possible to load more items'); + } + + if (!$not && $result !== 'OK') { + throw new DriverException('Error loading more items - ' . $result); + } + + return true; + }); + + $this->wait_for_pending_js(); + } + /** * Trigger swipe gesture. * @@ -1067,4 +1091,36 @@ class behat_app extends behat_base { } } + /** + * Evaludate a script that returns a Promise. + * + * @param string $script + * @return mixed Resolved promise result. + */ + private function evaluate_async_script(string $script) { + $script = preg_replace('/^return\s+/', '', $script); + $script = preg_replace('/;$/', '', $script); + $start = microtime(true); + $promisevariable = 'PROMISE_RESULT_' . time(); + $timeout = self::get_timeout(); + + $this->evaluate_script("Promise.resolve($script) + .then(result => window.$promisevariable = result) + .catch(error => window.$promisevariable = 'Async code rejected: ' + error?.message);"); + + do { + if (microtime(true) - $start > $timeout) { + throw new DriverException("Async script not resolved after $timeout seconds"); + } + + usleep(100000); + } while (!$this->evaluate_script("return '$promisevariable' in window;")); + + $result = $this->evaluate_script("return window.$promisevariable;"); + + $this->evaluate_script("delete window.$promisevariable;"); + + return $result; + } + } From aa9b943e057ddcbcf1d39fbcdd9f9db389fc7807 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 1 Dec 2021 17:33:15 +0100 Subject: [PATCH 162/220] MOBILE-3926 behat: Improve enter course step --- tests/behat/behat_app.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index c7f8b193d..051e8560b 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -585,14 +585,19 @@ class behat_app extends behat_base { /** * User enters a course in the app. * - * @Given /^I enter the course "(.+)" in the app$/ + * @Given /^I enter the course "(.+?)"(?: as "(.+)")? in the app$/ * @param string $coursename Course name * @throws DriverException If the button push doesn't work */ - public function i_enter_the_course_in_the_app(string $coursename) { - try { - $this->i_press_in_the_app('"My courses" near "Messages"'); - } catch (DriverException $e) { + public function i_enter_the_course_in_the_app(string $coursename, ?string $username = null) { + if (!is_null($username)) { + $this->i_enter_the_app(); + $this->login($username); + } + + $mycoursesfound = $this->evaluate_script("return window.behat.find({ text: 'My courses', near: { text: 'Messages' } });"); + + if ($mycoursesfound !== 'OK') { // My courses not present enter from Dashboard. $this->i_press_in_the_app('"Home" near "Messages"'); $this->i_press_in_the_app('"Dashboard"'); @@ -600,14 +605,13 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); - return true; + return; } + $this->i_press_in_the_app('"My courses" near "Messages"'); $this->i_press_in_the_app('"'.$coursename.'"'); $this->wait_for_pending_js(); - - return true; } /** From 4a091369257376844554be3a22a64c6937f96bae Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 22 Nov 2021 16:29:04 +0100 Subject: [PATCH 163/220] MOBILE-3926 assignment: Test navigation --- .../tests/behat/app_navigation.feature | 224 ++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 mod/assignment/tests/behat/app_navigation.feature diff --git a/mod/assignment/tests/behat/app_navigation.feature b/mod/assignment/tests/behat/app_navigation.feature new file mode 100644 index 000000000..b765b2a6e --- /dev/null +++ b/mod/assignment/tests/behat/app_navigation.feature @@ -0,0 +1,224 @@ +@mod @mod_assign @app @javascript +Feature: Test assignments navigation + + Background: + Given the following "users" exist: + | username | firstname | lastname | + | teacher1 | Teacher | teacher | + | student1 | First | Student | + | student2 | Second | Student | + | student3 | Third | Student | + And the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + | student3 | C1 | student | + And the following "groups" exist: + | name | course | idnumber | + | Group 1 | C1 | G1 | + | Group 2 | C1 | G2 | + And the following "group members" exist: + | user | group | + | student1 | G1 | + | student2 | G1 | + | student2 | G2 | + | student3 | G2 | + And the following "activities" exist: + | activity | name | course | idnumber | assignsubmission_onlinetext_enabled | duedate | groupmode | + | assign | Assignment | C1 | assignment | 1 | 0 | 1 | + And the following "mod_assign > submissions" exist: + | assign | user | onlinetext | + | assignment | student1 | Lorem | + | assignment | student3 | Ipsum | + + Scenario: Mobile navigation + Given I enter the course "Course 1" as "teacher1" in the app + + # Initial status + When I press "Assignment" in the app + Then I should find "3" near "Participants" in the app + And I should find "2" near "Drafts" in the app + + # Participants + When I press "Participants" in the app + Then I should find "First Student" in the app + And I should find "Second Student" in the app + And I should find "Third Student" in the app + + # Participants — swipe + When I press "First Student" in the app + And I swipe to the right in the app + Then I should find "First Student" in the app + But I should not find "Second Student" in the app + And I should not find "Third Student" in the app + + When I swipe to the left in the app + Then I should find "Third Student" in the app + But I should not find "First Student" in the app + And I should not find "Second Student" in the app + + When I swipe to the left in the app + Then I should find "Second Student" in the app + But I should not find "First Student" in the app + And I should not find "Third Student" in the app + + When I swipe to the left in the app + Then I should find "Second Student" in the app + But I should not find "First Student" in the app + And I should not find "Third Student" in the app + + # Drafts + When I press the back button in the app + And I press the back button in the app + And I press "Drafts" in the app + Then I should find "First Student" in the app + And I should find "Third Student" in the app + But I should not find "Second Student" in the app + + # Drafts — swipe + When I press "First Student" in the app + And I swipe to the right in the app + Then I should find "First Student" in the app + But I should not find "Second Student" in the app + And I should not find "Third Student" in the app + + When I swipe to the left in the app + Then I should find "Third Student" in the app + But I should not find "First Student" in the app + And I should not find "Second Student" in the app + + When I swipe to the left in the app + Then I should find "Third Student" in the app + But I should not find "First Student" in the app + And I should not find "Second Student" in the app + + # Filter groups in assignment page + When I press the back button in the app + And I press the back button in the app + And I press "Separate groups" in the app + And I press "Group 1" in the app + Then I should find "2" near "Participants" in the app + And I should find "1" near "Drafts" in the app + + When I press "Participants" in the app + Then I should find "First Student" in the app + And I should find "Second Student" in the app + But I should not find "Third Student" in the app + + When I press "First Student" in the app + And I swipe to the right in the app + Then I should find "First Student" in the app + But I should not find "Second Student" in the app + And I should not find "Third Student" in the app + + When I swipe to the left in the app + Then I should find "Second Student" in the app + But I should not find "First Student" in the app + And I should not find "Third Student" in the app + + When I swipe to the left in the app + Then I should find "Second Student" in the app + But I should not find "First Student" in the app + And I should not find "Third Student" in the app + + # Filter groups in submissions page + When I press the back button in the app + And I press "Separate groups" in the app + And I press "Group 2" in the app + Then I should find "Second Student" in the app + And I should find "Third Student" in the app + But I should not find "First Student" in the app + + When I press "Third Student" in the app + And I swipe to the right in the app + Then I should find "Third Student" in the app + But I should not find "First Student" in the app + And I should not find "Second Student" in the app + + When I swipe to the left in the app + Then I should find "Second Student" in the app + But I should not find "First Student" in the app + And I should not find "Third Student" in the app + + When I swipe to the left in the app + Then I should find "Second Student" in the app + But I should not find "First Student" in the app + And I should not find "Third Student" in the app + + Scenario: Tablet navigation + Given I enter the course "Course 1" as "teacher1" in the app + And I change viewport size to "1200x640" + + # Initial status + When I press "Assignment" in the app + Then I should find "3" near "Participants" in the app + And I should find "2" near "Drafts" in the app + + # Participants + When I press "Participants" in the app + Then I should find "First Student" in the app + And I should find "Second Student" in the app + And I should find "Third Student" in the app + And "First Student" near "Third Student" should be selected in the app + And I should find "First Student" inside the split-view content in the app + But I should not find "Second Student" inside the split-view content in the app + And I should not find "Third Student" inside the split-view content in the app + + # Participants — Split view + When I press "Second Student" in the app + Then "Second Student" near "Third Student" should be selected in the app + And I should find "Second Student" inside the split-view content in the app + But I should not find "First Student" inside the split-view content in the app + And I should not find "Third Student" inside the split-view content in the app + + # Drafts + When I press the back button in the app + And I press "Drafts" in the app + Then I should find "First Student" in the app + And I should find "Third Student" in the app + And "First Student" near "Third Student" should be selected in the app + And I should find "First Student" inside the split-view content in the app + But I should not find "Second Student" in the app + And I should not find "Third Student" inside the split-view content in the app + + # Drafts — Split view + When I press "Third Student" in the app + Then "Third Student" near "First Student" should be selected in the app + And I should find "Third Student" inside the split-view content in the app + But I should not find "First Student" inside the split-view content in the app + And I should not find "Second Student" in the app + + # Filter groups in assignment page + When I press the back button in the app + And I press "Separate groups" in the app + And I press "Group 1" in the app + Then I should find "2" near "Participants" in the app + And I should find "1" near "Drafts" in the app + + When I press "Participants" in the app + Then I should find "First Student" in the app + And I should find "Second Student" in the app + And "First Student" near "Second Student" should be selected in the app + And I should find "First Student" inside the split-view content in the app + But I should not find "Third Student" in the app + And I should not find "Second Student" inside the split-view content in the app + + # Filter groups in submissions page + When I press "Separate groups" in the app + And I press "Group 2" in the app + Then I should find "Second Student" in the app + And I should find "Third Student" in the app + And "Third Student" near "Second Student" should be selected in the app + And I should find "Third Student" inside the split-view content in the app + But I should not find "First Student" in the app + And I should not find "Second Student" inside the split-view content in the app + + When I press "Second Student" in the app + Then "Second Student" near "Third Student" should be selected in the app + And I should find "Second Student" inside the split-view content in the app + But I should not find "Third Student" inside the split-view content in the app + And I should not find "First Student" in the app From 2b93e0e5f9535652e51e8323c566dc1b2b4fefff Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 25 Nov 2021 13:05:02 +0100 Subject: [PATCH 164/220] MOBILE-3926 glossary: Test navigation --- .../tests/behat/app_navigation.feature | 289 ++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 mod/glossary/tests/behat/app_navigation.feature diff --git a/mod/glossary/tests/behat/app_navigation.feature b/mod/glossary/tests/behat/app_navigation.feature new file mode 100644 index 000000000..c3fac4b74 --- /dev/null +++ b/mod/glossary/tests/behat/app_navigation.feature @@ -0,0 +1,289 @@ +@mod @mod_glossary @app @javascript +Feature: Test glossary navigation + + Background: + Given the following "users" exist: + | username | firstname | lastname | + | student1 | First | Student | + | student2 | Second | Student | + And the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + And the following "activities" exist: + | activity | name | course | idnumber | displayformat | + | glossary | Fruits glossary | C1 | glossary | entrylist | + And the following "mod_glossary > entries" exist: + | glossary | concept | definition | user | + | glossary | Acerola | Acerola is a fruit | student1 | + | glossary | Apple | Apple is a fruit | student2 | + | glossary | Apricots | Apricots are a fruit | student1 | + | glossary | Avocado | Avocado is a fruit | student2 | + | glossary | Banana | Banana is a fruit | student1 | + | glossary | Blackberries | Blackberries is a fruit | student2 | + | glossary | Blackcurrant | Blackcurrant is a fruit | student1 | + | glossary | Blueberries | Blueberries is a fruit | student2 | + | glossary | Breadfruit | Breadfruit is a fruit | student1 | + | glossary | Cantaloupe | Cantaloupe is a fruit | student2 | + | glossary | Carambola | Carambola is a fruit | student1 | + | glossary | Cherimoya | Cherimoya is a fruit | student2 | + | glossary | Cherries | Cherries is a fruit | student1 | + | glossary | Clementine | Clementine is a fruit | student2 | + | glossary | Coconut | Coconut is a fruit | student1 | + | glossary | Cranberries | Cranberries is a fruit | student2 | + | glossary | Date Fruit | Date Fruit is a fruit | student1 | + | glossary | Durian | Durian is a fruit | student2 | + | glossary | Elderberries | Elderberries is a fruit | student1 | + | glossary | Feijoa | Feijoa is a fruit | student2 | + | glossary | Figs | Figs is a fruit | student1 | + | glossary | Gooseberries | Gooseberries are a fruit | student2 | + | glossary | Grapefruit | Grapefruit is a fruit | student1 | + | glossary | Grapes | Grapes are a fruit | student2 | + | glossary | Guava | Guava is a fruit | student1 | + | glossary | Honeydew Melon | Honeydew Melon is a fruit | student2 | + | glossary | Jackfruit | Jackfruit is a fruit | student1 | + | glossary | Java-Plum | Java-Plum is a fruit | student2 | + | glossary | Jujube Fruit | Jujube Fruit is a fruit | student1 | + | glossary | Kiwifruit | Kiwifruit is a fruit | student2 | + | glossary | Kumquat | Kumquat is a fruit | student1 | + | glossary | Lemon | Lemon is a fruit | student2 | + | glossary | lime | lime is a fruit | student1 | + | glossary | Lime | Lime is a fruit | student2 | + | glossary | Longan | Longan is a fruit | student1 | + | glossary | Loquat | Loquat is a fruit | student2 | + | glossary | Lychee | Lychee is a fruit | student1 | + | glossary | Mandarin | Mandarin is a fruit | student2 | + | glossary | Mango | Mango is a fruit | student1 | + | glossary | Mangosteen | Mangosteen is a fruit | student2 | + | glossary | Mulberries | Mulberries are a fruit | student1 | + | glossary | Nectarine | Nectarine is a fruit | student2 | + | glossary | Olives | Olives are a fruit | student1 | + | glossary | Orange | Orange is a fruit | student2 | + | glossary | Papaya | Papaya is a fruit | student1 | + | glossary | Passion Fruit | Passion Fruit is a fruit | student2 | + | glossary | Peaches | Peaches is a fruit | student1 | + | glossary | Pear | Pear is a fruit | student2 | + | glossary | Persimmon | Persimmon is a fruit | student1 | + | glossary | Pitaya | Pitaya is a fruit | student2 | + | glossary | Pineapple | Pineapple is a fruit | student1 | + | glossary | Pitanga | Pitanga is a fruit | student2 | + | glossary | Plantain | Plantain is a fruit | student1 | + | glossary | Plums | Plums are a fruit | student2 | + | glossary | Pomegranate | Pomegranate is a fruit | student1 | + | glossary | Prickly Pear | Prickly Pear is a fruit | student2 | + | glossary | Prunes | Prunes is a fruit | student1 | + | glossary | Pummelo | Pummelo is a fruit | student2 | + | glossary | Quince | Quince is a fruit | student1 | + | glossary | Raspberries | Raspberries are a fruit | student2 | + | glossary | Rhubarb | Rhubarb is a fruit | student1 | + | glossary | Rose-Apple | Rose-Apple is a fruit | student2 | + | glossary | Sapodilla | Sapodilla is a fruit | student1 | + | glossary | Sapote, Mamey | Sapote, Mamey is a fruit | student2 | + | glossary | Soursop | Soursop is a fruit | student1 | + | glossary | Strawberries | Strawberries is a fruit | student2 | + | glossary | Tamarind | Tamarind is a fruit | student2 | + | glossary | Tangerine | Tangerine is a fruit | student1 | + | glossary | Watermelon | Watermelon is a fruit | student2 | + + Scenario: Mobile navigation + Given I enter the course "Course 1" as "student1" in the app + + # Alphabetically + When I press "Fruits glossary" in the app + Then I should find "Acerola" in the app + And I should find "Apple" in the app + But I should not find "Honeydew Melon" in the app + + # Alphabetically — Infinite loading + When I load more items in the app + Then I should find "Honeydew Melon" in the app + + # Alphabetically — Swipe + When I press "Acerola" in the app + Then I should find "Acerola is a fruit" in the app + + When I swipe to the right in the app + Then I should find "Acerola is a fruit" in the app + + When I swipe to the left in the app + Then I should find "Apple is a fruit" in the app + + When I swipe to the left in the app + Then I should find "Apricots are a fruit" in the app + + # By author + When I press the back button in the app + And I scroll to "Acerola" in the app + And I press "Browse entries" in the app + And I press "Group by author" in the app + Then I should find "First Student" in the app + And I should find "Acerola" in the app + And I should find "Apricots" in the app + But I should not find "Second Student" in the app + And I should not find "Apple" in the app + + # By author — Infinite loading + When I load more items in the app + Then I should find "Second Student" in the app + And I should find "Apple" in the app + + # By author — Swipe + When I press "Acerola" in the app + Then I should find "Acerola is a fruit" in the app + + When I swipe to the right in the app + Then I should find "Acerola is a fruit" in the app + + When I swipe to the left in the app + Then I should find "Apricots are a fruit" in the app + + When I swipe to the left in the app + Then I should find "Banana is a fruit" in the app + + # Search + When I press the back button in the app + And I scroll to "Acerola" in the app + And I press "Search" in the app + And I set the field "Search" to "melon" in the app + And I press "Search" "button" near "Clear search" in the app + Then I should find "Honeydew Melon" in the app + And I should find "Watermelon" in the app + But I should not find "Acerola" in the app + + # Search — Swipe + When I press "Honeydew Melon" in the app + Then I should find "Honeydew Melon is a fruit" in the app + + When I swipe to the right in the app + Then I should find "Honeydew Melon is a fruit" in the app + + When I swipe to the left in the app + Then I should find "Watermelon is a fruit" in the app + + When I swipe to the left in the app + Then I should find "Watermelon is a fruit" in the app + + # Offline + When I press the back button in the app + And I press "Clear search" in the app + And I press "Add a new entry" in the app + And I switch offline mode to "true" + And I set the field "Concept" to "Tomato" in the app + And I set the field "Definition" to "Tomato is a fruit" in the app + And I press "Save" in the app + And I press "Add a new entry" in the app + And I set the field "Concept" to "Cashew" in the app + And I set the field "Definition" to "Cashew is a fruit" in the app + And I press "Save" in the app + Then I should find "Entries to be synced" in the app + And I should find "Tomato" in the app + And I should find "Cashew" in the app + + # Offline — Swipe + When I press "Cashew" in the app + Then I should find "Cashew is a fruit" in the app + + When I swipe to the right in the app + Then I should find "Cashew is a fruit" in the app + + When I swipe to the left in the app + Then I should find "Tomato is a fruit" in the app + + When I swipe to the left in the app + Then I should find "Acerola is a fruit" in the app + + Scenario: Tablet navigation + Given I enter the course "Course 1" as "student1" in the app + And I change viewport size to "1200x640" + + # Alphabetically + When I press "Fruits glossary" in the app + Then I should find "Acerola" in the app + And I should find "Apple" in the app + And "Acerola" near "Apple" should be selected in the app + And I should find "Acerola is a fruit" inside the split-view content in the app + But I should not find "Honeydew Melon" in the app + + # Alphabetically — Infinite loading + When I load more items in the app + Then I should find "Honeydew Melon" in the app + + # Alphabetically — Split view + When I press "Apple" in the app + Then "Apple" near "Acerola" should be selected in the app + And I should find "Apple is a fruit" inside the split-view content in the app + + When I press "Honeydew Melon" in the app + Then "Honeydew Melon" near "Guava" should be selected in the app + And I should find "Honeydew Melon is a fruit" inside the split-view content in the app + + # By author + When I press "Apple" in the app + When I scroll to "Apple" in the app + And I press "Browse entries" in the app + And I press "Group by author" in the app + Then I should find "First Student" in the app + And I should find "Acerola" in the app + And I should find "Apricots" in the app + And "Acerola" near "Apricots" should be selected in the app + And I should find "Acerola is a fruit" inside the split-view content in the app + But I should not find "Second Student" in the app + And I should not find "Apple" in the app + + # By author — Infinite loading + When I load more items in the app + Then I should find "Second Student" in the app + And I should find "Apple" in the app + + # By author — Split view + When I press "Apricots" in the app + And "Apricots" near "Acerola" should be selected in the app + And I should find "Apricots are a fruit" inside the split-view content in the app + + When I press "Apple" in the app + And "Apple" near "Persimmon" should be selected in the app + And I should find "Apple is a fruit" inside the split-view content in the app + + # Search + When I press "Search" in the app + And I set the field "Search" to "melon" in the app + And I press "Search" "button" near "Clear search" in the app + Then I should find "Honeydew Melon" in the app + And I should find "Watermelon" in the app + And "Honeydew Melon" near "Watermelon" should be selected in the app + And I should find "Honeydew Melon is a fruit" inside the split-view content in the app + But I should not find "Acerola" in the app + + # Search — Split view + When I press "Watermelon" in the app + Then "Watermelon" near "Honeydew Melon" should be selected in the app + And I should find "Watermelon is a fruit" inside the split-view content in the app + + # Offline + When I press "Clear search" in the app + And I press "Add a new entry" in the app + And I switch offline mode to "true" + And I set the field "Concept" to "Tomato" in the app + And I set the field "Definition" to "Tomato is a fruit" in the app + And I press "Save" in the app + And I set the field "Concept" to "Cashew" in the app + And I set the field "Definition" to "Cashew is a fruit" in the app + And I press "Save" in the app + Then I should find "Entries to be synced" in the app + And I should find "Tomato" in the app + And I should find "Cashew" in the app + + # Offline — Split view + When I press "Cashew" in the app + Then "Cashew" near "Tomato" should be selected in the app + And I should find "Cashew is a fruit" inside the split-view content in the app + + When I press "Tomato" in the app + Then "Tomato" near "Cashew" should be selected in the app + And I should find "Tomato is a fruit" inside the split-view content in the app + + When I press "Acerola" in the app + Then "Acerola" near "Tomato" should be selected in the app + And I should find "Acerola is a fruit" inside the split-view content in the app From 4c038fe3359fabe9972ca92919173e20881f9335 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 1 Dec 2021 14:13:19 +0100 Subject: [PATCH 165/220] MOBILE-3926 forum: Test navigation --- mod/forum/tests/behat/app_navigation.feature | 230 +++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 mod/forum/tests/behat/app_navigation.feature diff --git a/mod/forum/tests/behat/app_navigation.feature b/mod/forum/tests/behat/app_navigation.feature new file mode 100644 index 000000000..975887b6a --- /dev/null +++ b/mod/forum/tests/behat/app_navigation.feature @@ -0,0 +1,230 @@ +@mod @mod_forum @app @javascript +Feature: Test forum navigation + + Background: + Given the following "users" exist: + | username | firstname | lastname | + | student1 | First | Student | + And the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + And the following "activities" exist: + | activity | name | course | idnumber | + | forum | Forum | C1 | forum | + And the following "mod_forum > discussions" exist: + | forum | name | message | timenow | + | forum | Discussion 01 | Discussion 01 message | 1638200100 | + | forum | Discussion 02 | Discussion 02 message | 1638200200 | + | forum | Discussion 03 | Discussion 03 message | 1638200300 | + | forum | Discussion 04 | Discussion 04 message | 1638200400 | + | forum | Discussion 05 | Discussion 05 message | 1638200500 | + | forum | Discussion 06 | Discussion 06 message | 1638200600 | + | forum | Discussion 07 | Discussion 07 message | 1638200700 | + | forum | Discussion 08 | Discussion 08 message | 1638200800 | + | forum | Discussion 09 | Discussion 09 message | 1638200900 | + | forum | Discussion 10 | Discussion 10 message | 1638201000 | + | forum | Discussion 11 | Discussion 11 message | 1638201100 | + | forum | Discussion 12 | Discussion 12 message | 1638201200 | + | forum | Discussion 13 | Discussion 13 message | 1638201300 | + | forum | Discussion 14 | Discussion 14 message | 1638201400 | + | forum | Discussion 15 | Discussion 15 message | 1638201500 | + | forum | Discussion 16 | Discussion 16 message | 1638201600 | + | forum | Discussion 17 | Discussion 17 message | 1638201700 | + | forum | Discussion 18 | Discussion 18 message | 1638201800 | + | forum | Discussion 19 | Discussion 19 message | 1638201900 | + | forum | Discussion 20 | Discussion 20 message | 1638202000 | + And the following "mod_forum > posts" exist: + | discussion | parentsubject | message | + | Discussion 04 | Discussion 04 | Discussion 04 first reply | + | Discussion 05 | Discussion 05 | Discussion 05 first reply | + + Scenario: Mobile navigation + Given I enter the course "Course 1" as "student1" in the app + + # By last reply + When I press "Forum" in the app + Then I should find "Discussion 05" in the app + And I should find "Discussion 04" in the app + But I should not find "Discussion 12" in the app + + # By last reply — Infinite loading + When I load more items in the app + Then I should find "Discussion 12" in the app + And I should find "Discussion 01" in the app + But I should not be able to load more items in the app + + # By last reply — Swipe + When I press "Discussion 05" in the app + Then I should find "Discussion 05 first reply" in the app + + When I swipe to the right in the app + Then I should find "Discussion 05 first reply" in the app + + When I swipe to the left in the app + Then I should find "Discussion 04 first reply" in the app + + When I swipe to the left in the app + Then I should find "Discussion 20 message" in the app + + # By creation date + When I press the back button in the app + And I scroll to "Discussion 05" in the app + And I press "Sort" in the app + And I press "Sort by creation date in descending order" in the app + Then I should find "Discussion 20" in the app + And I should find "Discussion 19" in the app + But I should not find "Discussion 10" in the app + And I should not find "Discussion 04" in the app + And I should not find "Discussion 05" in the app + + # By creation date — Infinite loading + When I load more items in the app + Then I should find "Discussion 10" in the app + And I should find "Discussion 04" in the app + And I should find "Discussion 05" in the app + But I should not be able to load more items in the app + + # By creation date — Swipe + When I press "Discussion 20" in the app + Then I should find "Discussion 20 message" in the app + + When I swipe to the right in the app + Then I should find "Discussion 20 message" in the app + + When I swipe to the left in the app + Then I should find "Discussion 19 message" in the app + + When I swipe to the left in the app + Then I should find "Discussion 18 message" in the app + + # Offline + When I press the back button in the app + And I press "Add a new discussion topic" in the app + And I switch offline mode to "true" + And I set the field "Subject" to "Offline discussion 1" in the app + And I set the field "Message" to "Offline discussion 1 message" in the app + And I press "Post to forum" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "Offline discussion 2" in the app + And I set the field "Message" to "Offline discussion 2 message" in the app + And I press "Post to forum" in the app + Then I should find "Not sent" in the app + And I should find "Offline discussion 1" in the app + And I should find "Offline discussion 2" in the app + + When I press "Offline discussion 2" in the app + And I set the field "Subject" to "Offline discussion 3" in the app + And I set the field "Message" to "Offline discussion 3 message" in the app + And I press "Post to forum" in the app + Then I should find "Not sent" in the app + And I should find "Offline discussion 1" in the app + And I should find "Offline discussion 3" in the app + But I should not find "Offline discussion 2" in the app + + # Offline — Swipe + When I press "Offline discussion 3" in the app + Then I should find "Offline discussion 3 message" in the app + + When I swipe to the right in the app + Then I should find "Offline discussion 3 message" in the app + + When I swipe to the left in the app + Then I should find "Offline discussion 1 message" in the app + + When I swipe to the left in the app + Then I should find "Discussion 20 message" in the app + + Scenario: Tablet navigation + Given I enter the course "Course 1" as "student1" in the app + And I change viewport size to "1200x640" + + # By last reply + When I press "Forum" in the app + Then I should find "Discussion 04" in the app + And I should find "Discussion 05" in the app + And "Discussion 05" near "Discussion 04" should be selected in the app + And I should find "Discussion 05 first reply" inside the split-view content in the app + But I should not find "Discussion 12" in the app + + # By last reply — Infinite loading + When I load more items in the app + Then I should find "Discussion 12" in the app + And I should find "Discussion 01" in the app + But I should not be able to load more items in the app + + # By last reply — Split view + When I press "Discussion 04" in the app + Then "Discussion 04" near "Discussion 05" should be selected in the app + And I should find "Discussion 04 first reply" inside the split-view content in the app + + When I press "Discussion 12" in the app + Then "Discussion 12" near "Discussion 11" should be selected in the app + And I should find "Discussion 12 message" inside the split-view content in the app + + # By creation date + When I scroll to "Discussion 05" in the app + And I press "Discussion 05" in the app + And I press "Sort" in the app + And I press "Sort by creation date in descending order" in the app + Then I should find "Discussion 20" in the app + And I should find "Discussion 19" in the app + And "Discussion 20" near "Discussion 19" should be selected in the app + And I should find "Discussion 20 message" inside the split-view content in the app + But I should not find "Discussion 10" in the app + And I should not find "Discussion 04" in the app + And I should not find "Discussion 05" in the app + + # By creation date — Infinite loading + When I load more items in the app + Then I should find "Discussion 10" in the app + And I should find "Discussion 04" in the app + And I should find "Discussion 05" in the app + But I should not be able to load more items in the app + + # By creation date — Split view + When I press "Discussion 19" in the app + Then "Discussion 19" near "Discussion 20" should be selected in the app + And I should find "Discussion 19 message" inside the split-view content in the app + + When I press "Discussion 05" in the app + Then "Discussion 05" near "Discussion 04" should be selected in the app + And I should find "Discussion 05 first reply" inside the split-view content in the app + + # Offline + When I press "Add a new discussion topic" in the app + And I switch offline mode to "true" + And I set the field "Subject" to "Offline discussion 1" in the app + And I set the field "Message" to "Offline discussion 1 message" in the app + And I press "Post to forum" in the app + And I press "Add a new discussion topic" in the app + And I set the field "Subject" to "Offline discussion 2" in the app + And I set the field "Message" to "Offline discussion 2 message" in the app + And I press "Post to forum" in the app + Then I should find "Not sent" in the app + And I should find "Offline discussion 1" in the app + And I should find "Offline discussion 2" in the app + + When I press "Offline discussion 2" in the app + And I set the field "Subject" to "Offline discussion 3" in the app + And I set the field "Message" to "Offline discussion 3 message" in the app + And I press "Post to forum" in the app + Then I should find "Not sent" in the app + And I should find "Offline discussion 1" in the app + And I should find "Offline discussion 3" in the app + But I should not find "Offline discussion 2" in the app + + # Offline — Split view + When I press "Offline discussion 1" in the app + Then "Offline discussion 1" near "Offline discussion 3" should be selected in the app + And I should find "Offline discussion 1 message" inside the split-view content in the app + + When I press "Offline discussion 3" in the app + Then "Offline discussion 3" near "Offline discussion 1" should be selected in the app + And I should find "Offline discussion 3 message" inside the split-view content in the app + + When I press "Discussion 20" in the app + Then "Discussion 20" near "Discussion 19" should be selected in the app + And I should find "Discussion 20 message" inside the split-view content in the app From b99f47e3308ea98477f35181e7cc9aca1fc1fefd Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 20 Dec 2021 17:25:48 +0100 Subject: [PATCH 166/220] MOBILE-3833 behat: Fix popovers interaction --- mod/forum/tests/behat/app_basic_usage.feature | 3 ++- mod/messages/tests/behat/app_basic_usage.feature | 4 ++-- mod/messages/tests/behat/navigation.feature | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index c9c5ad14e..681e6219f 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -240,7 +240,8 @@ Feature: Test basic usage of forum activity in app And I press "Display options" near "Reply" in the app Then I should not find "Delete" in the app - When I switch offline mode to "false" + When I close the popup in the app + And I switch offline mode to "false" And I press "Display options" near "Reply" in the app And I press "Delete" in the app And I press "Delete" in the app diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index 7af987d3f..dad30af63 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -158,8 +158,7 @@ Feature: Test basic usage of messages in app And I press "Display options" in the app Then I should find "Add to contacts" in the app - When I press "Display options" in the app - And I press "Delete conversation" in the app + When I press "Delete conversation" in the app And I press "Delete" near "Are you sure you would like to delete this entire conversation?" in the app Then I should not find "heeey student" in the app And I should not find "hi" in the app @@ -392,6 +391,7 @@ Feature: Test basic usage of messages in app And I should find "Delete conversation" in the app When I press "Show delete messages" in the app + And I close the popup in the app Then I should find "self conversation online" in the app And I should find "self conversation offline" in the app diff --git a/mod/messages/tests/behat/navigation.feature b/mod/messages/tests/behat/navigation.feature index 15bded770..5be92c2ca 100644 --- a/mod/messages/tests/behat/navigation.feature +++ b/mod/messages/tests/behat/navigation.feature @@ -37,6 +37,7 @@ Feature: Test messages navigation in the app When I press "Display options" in the app Then I should not find "User info" in the app - When I press the back button in the app + When I close the popup in the app + And I press the back button in the app And I press the back button in the app Then I should find "Hi there" in the app From f768a19748424b458c290e4d6e5eeba4afd60b5a Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 20 Dec 2021 17:31:54 +0100 Subject: [PATCH 167/220] MOBILE-3833 behat: Fix changes in LMS UI --- .../tests/behat/app_basic_usage.feature | 1 - .../tests/behat/app_basic_usage.feature | 39 ++++--------------- .../tests/behat/app_basic_usage.feature | 9 +---- 3 files changed, 9 insertions(+), 40 deletions(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 00622c74d..f4e85faaf 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -199,7 +199,6 @@ Feature: Test basic usage of choice activity in app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" - And I press "Actions menu" And I follow "Responses" And I press "Download in text format" # TODO Then I should find "..." in the downloads folder diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index d9e26d457..eee70602a 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -415,10 +415,8 @@ Feature: Test basic usage of one course in app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" - And I press "Actions menu" - And I follow "More..." - And I follow "Users" - And I follow "Enrolment methods" + And I click on "Participants" "link" + And I select "Enrolment methods" from the "jump" singleselect And I click on "Enable" "icon" in the "Self enrolment (Student)" "table_row" And I close the browser tab opened by the app When I enter the app @@ -455,10 +453,8 @@ Feature: Test basic usage of one course in app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" - And I press "Actions menu" - And I follow "More..." - And I follow "Users" - And I follow "Enrolment methods" + And I click on "Participants" "link" + And I select "Enrolment methods" from the "jump" singleselect And I click on "Enable" "icon" in the "Guest access" "table_row" And I close the browser tab opened by the app When I enter the app @@ -485,30 +481,11 @@ Feature: Test basic usage of one course in app And I should find "Test scorm name" in the app And I should find "Test workshop name" in the app - # TODO remove LMS UI steps in app tests Scenario: View blocks on drawer - Given I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app - And I press "Display options" in the app - And I press "Course summary" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "teacher1" - And I click on "Edit mode" "checkbox" - And I click on "Side panel" "button" - And I follow "Add a block" - And I follow "Text" - And I click on "Side panel" "button" - And I follow "Add a block" - And I follow "Activities" - And I click on "Open block drawer" "button" - And I click on "Actions menu" "icon" in the "#action-menu-toggle-0" "css_element" - And I follow "Configure (new text block) block" - And I set the field "Text block title" to "HTML title test" - And I set the field "Content" to "body test" - And I press "Save changes" - And I close the browser tab opened by the app + Given the following "blocks" exist: + | blockname | contextlevel | reference | pagetypepattern | defaultregion | configdata | + | html | Course | C1 | course-view-* | site-pre | Tzo4OiJzdGRDbGFzcyI6Mjp7czo1OiJ0aXRsZSI7czoxNToiSFRNTCB0aXRsZSB0ZXN0IjtzOjQ6InRleHQiO3M6OToiYm9keSB0ZXN0Ijt9 | + | activity_modules | Course | C1 | course-view-* | site-pre | | When I enter the app And I log in as "student1" And I enter the course "Course 1" in the app diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index 7dc6932ef..5d142bd06 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -101,12 +101,7 @@ Feature: Test basic usage of courses in app # TODO remove LMS UI steps in app tests Scenario: Links to actions in Timeline work for teachers/students # Configure assignment as teacher - When I enter the app - And I log in as "teacher1" - Then I press "Open block drawer" in the app - Then I should find "Timeline" in the app - - Given I press "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "assignment" in the app And I press "Display options" in the app And I press "Open in browser" in the app @@ -123,7 +118,6 @@ Feature: Test basic usage of courses in app # Submit assignment as student When I enter the app And I log in as "student1" - Then I press "Open block drawer" in the app And I press "Add submission" in the app Then the header should be "assignment" in the app And I should find "Test assignment description" in the app @@ -143,7 +137,6 @@ Feature: Test basic usage of courses in app # Grade assignment as teacher When I enter the app And I log in as "teacher1" - Then I press "Open block drawer" in the app And I press "Grade" in the app Then the header should be "assignment" in the app And I should find "Test assignment description" in the app From 4452bd58751e8aab8f1f0049793e9b7fe268ffd2 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 20 Dec 2021 17:35:26 +0100 Subject: [PATCH 168/220] MOBILE-3833 behat: Simplify entering the app --- .../tests/behat/app_basic_usage.feature | 32 +++------- mod/chat/tests/behat/app_basic_usage.feature | 16 ++--- .../tests/behat/app_basic_usage.feature | 28 +++------ .../tests/behat/app_basic_usage.feature | 48 ++++----------- .../tests/behat/app_basic_usage.feature | 24 ++------ .../tests/behat/app_course_completion.feature | 4 +- mod/data/tests/behat/app_data_entries.feature | 32 +++------- mod/data/tests/behat/app_data_sync.feature | 12 +--- mod/forum/tests/behat/app_basic_usage.feature | 60 +++++-------------- .../tests/behat/app_basic_usage.feature | 48 ++++----------- .../tests/behat/app_basic_usage.feature | 20 ++----- mod/quiz/tests/behat/app_basic_usage.feature | 16 ++--- .../tests/behat/app_basic_usage.feature | 28 +++------ tests/behat/navigation_activities.feature | 4 +- tests/behat/navigation_externallinks.feature | 4 +- tests/behat/navigation_gestures.feature | 8 +-- 16 files changed, 96 insertions(+), 288 deletions(-) diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index 1c4fd025d..e3b536b98 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -21,9 +21,7 @@ Feature: Test basic usage of assignment activity in app Scenario: View assign description, due date & View list of student submissions (as teacher) & View own submission or student submission # Create, edit and submit as a student - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "assignment1" in the app Then the header should be "assignment1" in the app And I should find "Test assignment description1" in the app @@ -49,9 +47,7 @@ Feature: Test basic usage of assignment activity in app And I should find "Submission test edited" in the app # View as a teacher - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "assignment1" in the app Then the header should be "assignment1" in the app @@ -65,9 +61,7 @@ Feature: Test basic usage of assignment activity in app Scenario: Edit/Add submission (online text) & Add new attempt from previous submission & Submit for grading # Submit first attempt as a student - Given I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "student1" in the app And I press "assignment1" in the app And I press "Add submission" in the app And I set the field "Online text submissions" to "Submission test 1st attempt" in the app @@ -76,9 +70,7 @@ Feature: Test basic usage of assignment activity in app And I press "OK" in the app # Allow more attempts as a teacher - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "assignment1" in the app And I press "Participants" in the app And I press "Student student" near "assignment1" in the app @@ -89,9 +81,7 @@ Feature: Test basic usage of assignment activity in app And I should find "Not graded" in the app # Submit second attempt as a student - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "assignment1" in the app Then I should find "Reopened" in the app And I should find "2 out of Unlimited" in the app @@ -109,9 +99,7 @@ Feature: Test basic usage of assignment activity in app And I press "OK" in the app # View second attempt as a teacher - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "assignment1" in the app And I press "Participants" in the app And I press "Student student" near "assignment1" in the app @@ -119,9 +107,7 @@ Feature: Test basic usage of assignment activity in app And I should find "Submission test 2nd attempt" in the app Scenario: Add submission offline (online text) & Submit for grading offline & Sync submissions - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "assignment1" in the app And I press "Add submission" in the app And I switch offline mode to "true" @@ -140,9 +126,7 @@ Feature: Test basic usage of assignment activity in app But I should not find "This Assignment has offline data to be synchronised." in the app Scenario: Edit an offline submission before synchronising it - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "assignment1" in the app And I press "Add submission" in the app And I switch offline mode to "true" diff --git a/mod/chat/tests/behat/app_basic_usage.feature b/mod/chat/tests/behat/app_basic_usage.feature index 3a09d3c86..f3727631f 100755 --- a/mod/chat/tests/behat/app_basic_usage.feature +++ b/mod/chat/tests/behat/app_basic_usage.feature @@ -21,9 +21,7 @@ Feature: Test basic usage of chat in app Scenario: Receive and send messages & See connected users, beep and talk to # Send messages as student1 - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test chat name" in the app Then I should find "Click here to enter the chat now" in the app And I should find "View past chat sessions" in the app @@ -39,9 +37,7 @@ Feature: Test basic usage of chat in app And I should find "I am David" in the app # Read messages, view connected users, send beep and reply as student2 - When I enter the app - And I log in as "student2" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student2" in the app And I press "Test chat name" in the app And I press "Click here to enter the chat now" in the app Then I should find "Hi!" in the app @@ -59,9 +55,7 @@ Feature: Test basic usage of chat in app Scenario: Past sessions shown # Send messages as student1 - Given I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "student1" in the app And I press "Test chat name" in the app And I press "Click here to enter the chat now" in the app And I set the field "New message" to "Hi!" in the app @@ -73,9 +67,7 @@ Feature: Test basic usage of chat in app Then I should find "I am David" in the app # Read messages from past sessions as student2 - When I enter the app - And I log in as "student2" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student2" in the app And I press "Test chat name" in the app And I press "View past chat sessions" in the app And I press "Show incomplete sessions" in the app diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index f4e85faaf..abf5a0c53 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -21,9 +21,7 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test single choice name" in the app And I select "Option 1" in the app And I select "Option 2" in the app @@ -46,9 +44,7 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test multi choice name" in the app And I select "Option 1" in the app And I select "Option 2" in the app @@ -76,9 +72,7 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test single choice name" in the app And I select "Option 1" in the app And I switch offline mode to "true" @@ -110,9 +104,7 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test single choice name" in the app And I select "Option 1" in the app And I switch offline mode to "true" @@ -139,9 +131,7 @@ Feature: Test basic usage of choice activity in app | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Display options" in the app And I press "Show download options" in the app And I press "Download" near "Test single choice name" in the app @@ -180,18 +170,14 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | - And I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + And I enter the course "Course 1" as "student1" in the app And I press "Choice name" in the app And I select "Option 2" in the app And I press "Save my choice" in the app And I press "OK" in the app # Download answers as teacher - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Choice name" in the app Then I should find "Test choice description" in the app diff --git a/mod/comments/tests/behat/app_basic_usage.feature b/mod/comments/tests/behat/app_basic_usage.feature index 9064d47ab..c398038d4 100755 --- a/mod/comments/tests/behat/app_basic_usage.feature +++ b/mod/comments/tests/behat/app_basic_usage.feature @@ -26,9 +26,7 @@ Feature: Test basic usage of comments in app @app @3.8.0 Scenario: Add comments & Delete comments (database) # Create database entry and comment as a teacher - Given I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "teacher1" in the app And I press "Data" in the app And I press "Display options" in the app And I press "Open in browser" in the app @@ -39,9 +37,7 @@ Feature: Test basic usage of comments in app | Field description | Test field description | And I press "Save" And I close the browser tab opened by the app - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Data" in the app And I press "add" in the app And I set the field "Test field name" to "Test" in the app @@ -58,9 +54,7 @@ Feature: Test basic usage of comments in app And I should see "Comments (1)" # Create and delete comments as a student - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Data" in the app And I press "More" in the app And I press "Comments (1)" in the app @@ -85,9 +79,7 @@ Feature: Test basic usage of comments in app @app @3.8.0 Scenario: Add comments offline & Delete comments offline & Sync comments (database) - Given I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "teacher1" in the app And I press "Data" in the app And I press "Display options" in the app And I press "Open in browser" in the app @@ -98,9 +90,7 @@ Feature: Test basic usage of comments in app | Field description | Test field description | And I press "Save" And I close the browser tab opened by the app - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Data" in the app And I press "add" in the app And I set the field "Test field name" to "Test" in the app @@ -148,9 +138,7 @@ Feature: Test basic usage of comments in app @app @3.8.0 Scenario: Add comments & delete comments (glossary) # Create glossary entry and comment as a teacher - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -167,9 +155,7 @@ Feature: Test basic usage of comments in app And I should see "Comments (1)" # Create and delete comments as a student - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test glossary" in the app And I press "potato" in the app And I press "Comments (1)" in the app @@ -194,9 +180,7 @@ Feature: Test basic usage of comments in app @app @3.8.0 Scenario: Add comments offline & Delete comments offline & Sync comments (glossary) - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -245,9 +229,7 @@ Feature: Test basic usage of comments in app @app @3.8.0 Scenario: Add comments & Delete comments (blogs) # Create blog as a teacher - Given I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "teacher1" in the app And I press "menu" in the app And I press "Website" in the app And I switch to the browser tab opened by the app @@ -266,9 +248,7 @@ Feature: Test basic usage of comments in app And I close the browser tab opened by the app # Create and delete comments as a student - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "menu" in the app And I press "Site blog" in the app Then I should see "Blog test" @@ -295,9 +275,7 @@ Feature: Test basic usage of comments in app @app @3.8.0 Scenario: Add comments offline & Delete comments offline & Sync comments (blogs) # Create blog as a teacher - Given I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "teacher1" in the app And I press "menu" in the app And I press "Website" in the app And I switch to the browser tab opened by the app @@ -316,9 +294,7 @@ Feature: Test basic usage of comments in app And I close the browser tab opened by the app # Create and delete comments as a student - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "menu" in the app And I press "Site blog" in the app Then I should see "Blog test" diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index eee70602a..a51cec01e 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -72,9 +72,7 @@ Feature: Test basic usage of one course in app | workshop | Test workshop name | Test workshop | C1 | workshop | 0 | 3 | Scenario: View course contents - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -149,9 +147,7 @@ Feature: Test basic usage of one course in app Then the header should be "Test workshop name" in the app Scenario: View section contents - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -328,9 +324,7 @@ Feature: Test basic usage of one course in app Then the header should be "Test glossary" in the app Scenario: Navigation between sections using the bottom arrows - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -407,9 +401,7 @@ Feature: Test basic usage of one course in app And I should not find "Topic 2" in the app Scenario: Self enrol - Given I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "teacher1" in the app And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app @@ -445,9 +437,7 @@ Feature: Test basic usage of one course in app And I should find "Test workshop name" in the app Scenario: Guest access - Given I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "teacher1" in the app And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app @@ -486,9 +476,7 @@ Feature: Test basic usage of one course in app | blockname | contextlevel | reference | pagetypepattern | defaultregion | configdata | | html | Course | C1 | course-view-* | site-pre | Tzo4OiJzdGRDbGFzcyI6Mjp7czo1OiJ0aXRsZSI7czoxNToiSFRNTCB0aXRsZSB0ZXN0IjtzOjQ6InRleHQiO3M6OToiYm9keSB0ZXN0Ijt9 | | activity_modules | Course | C1 | course-view-* | site-pre | | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app diff --git a/mod/course/tests/behat/app_course_completion.feature b/mod/course/tests/behat/app_course_completion.feature index 52a23b979..999b55736 100644 --- a/mod/course/tests/behat/app_course_completion.feature +++ b/mod/course/tests/behat/app_course_completion.feature @@ -20,9 +20,7 @@ Feature: Check course completion feature. | activity | name | course | idnumber | completion | completionview | | forum | First forum | C1 | forum1 | 1 | 0 | | forum | Second forum | C1 | forum2 | 1 | 0 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app # Set activities as completed. And I should find "0%" in the app And I press "Mark First forum as done" in the app diff --git a/mod/data/tests/behat/app_data_entries.feature b/mod/data/tests/behat/app_data_entries.feature index dd8c5621b..ca214a012 100644 --- a/mod/data/tests/behat/app_data_entries.feature +++ b/mod/data/tests/behat/app_data_entries.feature @@ -32,9 +32,7 @@ Feature: Users can manage entries in database activities And I log out Scenario: Create entry - Given I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "student1" in the app And I press "Web links" near "General" in the app And I should see "No entries in database" When I press "Add entries" in the app @@ -45,17 +43,13 @@ Feature: Users can manage entries in database activities And I should see "Moodle community site" Scenario: Browse entry - Given I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "student1" in the app And I press "Web links" near "General" in the app And I press "Add entries" in the app And I set the field "URL" to "https://moodle.org/" in the app And I set the field "Description" to "Moodle community site" in the app And I press "Save" near "Web links" in the app - When I enter the app - And I log in as "student2" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student2" in the app And I press "Web links" near "General" in the app And I press "Add entries" in the app And I set the field "URL" to "https://moodlecloud.com/" in the app @@ -77,17 +71,13 @@ Feature: Users can manage entries in database activities And I should see "Moodle Cloud" Scenario: Students can not edit or delete other user's entries from list and single view in the app - Given I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "student1" in the app And I press "Web links" near "General" in the app And I press "Add entries" in the app And I set the field "URL" to "https://moodle.org/" in the app And I set the field "Description" to "Moodle community site" in the app And I press "Save" near "Web links" in the app - When I enter the app - And I log in as "student2" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student2" in the app And I press "Web links" near "General" in the app Then "Edit" "link" should not exist And "Delete" "link" should not exist @@ -96,9 +86,7 @@ Feature: Users can manage entries in database activities And "Delete" "link" should not exist Scenario: Delete entry (student) & Update entry (student) - Given I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "student1" in the app And I press "Web links" near "General" in the app And I press "Add entries" in the app And I set the field "URL" to "https://moodle.org/" in the app @@ -144,9 +132,7 @@ Feature: Users can manage entries in database activities And I should see "No entries in database" Scenario: Delete entry (teacher) & Update entry (teacher) - Given I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "student1" in the app And I press "Web links" near "General" in the app And I press "Add entries" in the app And I set the field "URL" to "https://moodle.org/" in the app @@ -156,9 +142,7 @@ Feature: Users can manage entries in database activities And I set the field "URL" to "https://telegram.org/" in the app And I set the field "Description" to "Telegram" in the app And I press "Save" near "Web links" in the app - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Web links" near "General" in the app Then I should see "https://moodle.org/" And I should see "Moodle community site" diff --git a/mod/data/tests/behat/app_data_sync.feature b/mod/data/tests/behat/app_data_sync.feature index ff9b47a4f..04cc1c2c3 100644 --- a/mod/data/tests/behat/app_data_sync.feature +++ b/mod/data/tests/behat/app_data_sync.feature @@ -33,9 +33,7 @@ Feature: Users can store entries in database activities when offline and sync wh @app_from3.7 Scenario: Create entry (offline) - Given I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "student1" in the app And I press "Web links" near "General" in the app And I switch offline mode to "true" And I should see "No entries in database" @@ -55,9 +53,7 @@ Feature: Users can store entries in database activities when offline and sync wh @app_from3.7 Scenario: Update entry (offline) & Delete entry (offline) - Given I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "student1" in the app And I press "Web links" near "General" in the app And I should see "No entries in database" And I press "Add entries" in the app @@ -106,9 +102,7 @@ Feature: Users can store entries in database activities when offline and sync wh @app_from3.7 Scenario: Students can undo deleting entries to a database in the app while offline - Given I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "student1" in the app And I press "Web links" near "General" in the app And I should see "No entries in database" And I press "Add entries" in the app diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 681e6219f..6789902d1 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -25,9 +25,7 @@ Feature: Test basic usage of forum activity in app | forum | Test forum name | Test forum | C1 | forum | 0 | 1 | 1 | Scenario: Create new discussion - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "My happy subject" in the app @@ -39,9 +37,7 @@ Feature: Test basic usage of forum activity in app Then I should find "An awesome message" in the app Scenario: Reply a post - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app @@ -57,9 +53,7 @@ Feature: Test basic usage of forum activity in app And I should find "ReplyMessage" in the app Scenario: Star and pin discussions (student) - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "starred subject" in the app @@ -93,9 +87,7 @@ Feature: Test basic usage of forum activity in app Then I should find "normal message" in the app Scenario: Star and pin discussions (teacher) - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test star" in the app @@ -125,9 +117,7 @@ Feature: Test basic usage of forum activity in app And I should find "Auto-test pin" in the app Scenario: Edit a not sent reply offline - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app @@ -160,9 +150,7 @@ Feature: Test basic usage of forum activity in app And I should not find "This Discussion has offline data to be synchronised" in the app Scenario: Edit a not sent new discussion offline - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I switch offline mode to "true" And I press "Add a new discussion topic" in the app @@ -185,9 +173,7 @@ Feature: Test basic usage of forum activity in app And I should find "Auto-test message edited" in the app Scenario: Edit a forum post (only online) - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app @@ -213,9 +199,7 @@ Feature: Test basic usage of forum activity in app Then I should find "There was a problem connecting to the site. Please check your connection and try again." in the app Scenario: Delete a forum post (only online) - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app @@ -248,9 +232,7 @@ Feature: Test basic usage of forum activity in app Then I should not find "Auto-test" in the app Scenario: Add/view ratings - Given I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + Given I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app @@ -262,9 +244,7 @@ Feature: Test basic usage of forum activity in app When I press "Reply" in the app And I set the field "Message" to "test2" in the app And I press "Post to forum" in the app - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Test forum name" in the app And I press "Auto-test" in the app Then I should find "Reply" in the app @@ -291,9 +271,7 @@ Feature: Test basic usage of forum activity in app And I should find "Average of ratings: 0" in the app But I should not find "Average of ratings: -" in the app - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I press "Auto-test" in the app Then I should find "Average of ratings: 1" in the app @@ -301,9 +279,7 @@ Feature: Test basic usage of forum activity in app But I should not find "Average of ratings: -" in the app Scenario: Reply a post offline - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app @@ -333,9 +309,7 @@ Feature: Test basic usage of forum activity in app But I should not find "Not sent" in the app Scenario: New discussion offline & Sync Forum - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I switch offline mode to "true" And I press "Add a new discussion topic" in the app @@ -358,9 +332,7 @@ Feature: Test basic usage of forum activity in app And I should not find "This Forum has offline data to be synchronised." in the app Scenario: New discussion offline & Auto-sync forum - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I switch offline mode to "true" And I press "Add a new discussion topic" in the app @@ -383,9 +355,7 @@ Feature: Test basic usage of forum activity in app And I should not find "This Forum has offline data to be synchronised." in the app Scenario: Prefetch - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I press "Add a new discussion topic" in the app And I set the field "Subject" to "DiscussionSubject 1" in the app diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/mod/glossary/tests/behat/app_basic_usage.feature index fee4f409d..5fcb2e3dd 100755 --- a/mod/glossary/tests/behat/app_basic_usage.feature +++ b/mod/glossary/tests/behat/app_basic_usage.feature @@ -27,9 +27,7 @@ Feature: Test basic usage of glossary in app @app @3.8.0 Scenario: View a glossary and its terms - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -54,9 +52,7 @@ Feature: Test basic usage of glossary in app @app @3.8.0 Scenario: Change filters (include search) - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -92,9 +88,7 @@ Feature: Test basic usage of glossary in app @app @3.8.0 Scenario: Navigate to glossary terms by link (auto-linking) When the "glossary" filter is "on" - And I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + And I enter the course "Course 1" as "student1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -137,9 +131,7 @@ Feature: Test basic usage of glossary in app @app @3.8.0 Scenario: See comments # Create entries as a student - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -162,9 +154,7 @@ Feature: Test basic usage of glossary in app Then I should see "Comments (0)" # Write comments as a teacher - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then I should see "Comments (0)" @@ -184,9 +174,7 @@ Feature: Test basic usage of glossary in app And I should see "teacher second comment" # View comments as a student - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then I should see "Comments (2)" @@ -197,9 +185,7 @@ Feature: Test basic usage of glossary in app @app @3.8.0 Scenario: Prefetch - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -238,9 +224,7 @@ Feature: Test basic usage of glossary in app @app @3.8.0 Scenario: Sync - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test glossary" in the app And I switch offline mode to "true" And I press "close" in the app @@ -280,9 +264,7 @@ Feature: Test basic usage of glossary in app @app @3.8.0 Scenario: Add/view ratings # Create entries as a student - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test glossary" in the app And I press "close" in the app And I set the field "Concept" to "potato" in the app @@ -302,9 +284,7 @@ Feature: Test basic usage of glossary in app And I should see "potato" # Rate entries as teacher1 - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then I should see "Average of ratings: -" @@ -314,9 +294,7 @@ Feature: Test basic usage of glossary in app Then I should see "Average of ratings: 1" # Rate entries as teacher2 - When I enter the app - And I log in as "teacher2" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher2" in the app And I press "Test glossary" in the app And I press "mountain" in the app And I switch offline mode to "true" @@ -335,9 +313,7 @@ Feature: Test basic usage of glossary in app Then I should see "Average of ratings: 0.5" # View ratings as a student - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test glossary" in the app And I press "mountain" in the app Then the header should be "mountain" in the app diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/mod/messages/tests/behat/app_basic_usage.feature index dad30af63..3d2fe7489 100755 --- a/mod/messages/tests/behat/app_basic_usage.feature +++ b/mod/messages/tests/behat/app_basic_usage.feature @@ -289,9 +289,7 @@ Feature: Test basic usage of messages in app And I should find "Student1 student1" in the app Scenario: User blocking feature - When I enter the app - And I log in as "student2" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student2" in the app And I press "Participants" in the app And I press "Student1 student1" in the app And I press "Message" in the app @@ -300,17 +298,13 @@ Feature: Test basic usage of messages in app And I press "Block user" near "Are you sure you want to block Student1 student1?" in the app Then I should find "You have blocked this user" in the app - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app Then I should find "You are unable to message this user" in the app - When I enter the app - And I log in as "student2" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student2" in the app And I press "Participants" in the app And I press "Student1 student1" in the app And I press "Message" in the app @@ -322,9 +316,7 @@ Feature: Test basic usage of messages in app And I press "Unblock user" near "Are you sure you want to unblock Student1 student1?" in the app Then I should not find "You have blocked this user" in the app - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app @@ -334,9 +326,7 @@ Feature: Test basic usage of messages in app But I should not find "You are unable to message this user" in the app Scenario: Mute Unmute conversations - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app diff --git a/mod/quiz/tests/behat/app_basic_usage.feature b/mod/quiz/tests/behat/app_basic_usage.feature index ead2f1454..493b7acf0 100755 --- a/mod/quiz/tests/behat/app_basic_usage.feature +++ b/mod/quiz/tests/behat/app_basic_usage.feature @@ -56,9 +56,7 @@ Feature: Attempt a quiz in app | TF9 | 7 | Scenario: View a quiz entry page (attempts, status, etc.) - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Quiz 1" in the app And I press "Attempt quiz now" in the app Then I should find "Text of the first question" in the app @@ -108,9 +106,7 @@ Feature: Attempt a quiz in app And I should find "Question 2" in the app Scenario: Attempt a quiz (all question types) - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Quiz 2" in the app And I press "Attempt quiz now" in the app And I press "Four" in the app @@ -147,9 +143,7 @@ Feature: Attempt a quiz in app And I should find "Not yet graded" in the app Scenario: Submit a quiz & Review a quiz attempt - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Quiz 1" in the app And I press "Attempt quiz now" in the app And I press "True" in the app @@ -160,9 +154,7 @@ Feature: Attempt a quiz in app And I press "OK" in the app Then I should find "Review of attempt 1" in the app - When I enter the app - And I log in as "teacher1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Quiz 1" in the app And I press "Display options" in the app And I press "Open in browser" in the app diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index 4a0004b43..d9744cd6f 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -22,9 +22,7 @@ Feature: Test basic usage of survey activity in app @app @3.8.0 Scenario: Answer a survey & View results (ATTLS) - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test survey name" in the app And I press "Choose" near "1. In evaluating what someone says, I focus on the quality of their argument, not on the person who's presenting it." in the app And I press "Strongly agree" in the app @@ -79,9 +77,7 @@ Feature: Test basic usage of survey activity in app Given the following "activities" exist: | activity | name | intro | template |course | idnumber | groupmode | | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test survey critical incidents" in the app And I set the field with xpath "//textarea[@aria-label='At what moment in class were you most engaged as a learner?']" to "1st answer" And I set the field with xpath "//textarea[@aria-label='At what moment in class were you most distanced as a learner?']" to "2nd answer" @@ -107,9 +103,7 @@ Feature: Test basic usage of survey activity in app Given the following "activities" exist: | activity | name | intro | template |course | idnumber | groupmode | | survey | Test survey Colles (actual) | Test survey1 | 1 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test survey Colles (actual)" in the app And I press "Choose" near "1. my learning focuses on issues that interest me." in the app And I press "Sometimes" near "Often" in the app @@ -176,9 +170,7 @@ Feature: Test basic usage of survey activity in app Given the following "activities" exist: | activity | name | intro | template | course | idnumber | groupmode | | survey | Test survey Colles (preferred) | Test survey1 | 2 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test survey Colles (preferred)" in the app And I press "Choose" near "1. my learning focuses on issues that interest me." in the app And I press "Sometimes" near "Often" in the app @@ -245,9 +237,7 @@ Feature: Test basic usage of survey activity in app Given the following "activities" exist: | activity | name | intro | template | course | idnumber | groupmode | | survey | Test survey Colles (preferred and actual) | Test survey1 | 3 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test survey Colles (preferred and actual)" in the app And I press "Choose" near "1. I prefer that my learning focuses on issues that interest me." in the app And I press "Sometimes" near "Often" in the app @@ -362,9 +352,7 @@ Feature: Test basic usage of survey activity in app Given the following "activities" exist: | activity | name | intro | template | course | idnumber | groupmode | | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test survey critical incidents" in the app And I switch offline mode to "true" And I press "Submit" in the app @@ -385,9 +373,7 @@ Feature: Test basic usage of survey activity in app Given the following "activities" exist: | activity | name | intro | template | course | idnumber | groupmode | | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Display options" in the app And I press "Show download options" in the app And I press "cloud download" near "Test survey critical incidents" in the app diff --git a/tests/behat/navigation_activities.feature b/tests/behat/navigation_activities.feature index a11144da3..1c93c11be 100644 --- a/tests/behat/navigation_activities.feature +++ b/tests/behat/navigation_activities.feature @@ -18,9 +18,7 @@ Feature: It navigates properly within activities. And I replace the arguments in "page" "content" Scenario: Navigates using deep links - When I enter the app - And I log in as "student" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student" in the app And I press "Page" in the app And I press "Go to label" in the app Then I should find "Label description" in the app diff --git a/tests/behat/navigation_externallinks.feature b/tests/behat/navigation_externallinks.feature index 1be8c2d91..febd346b5 100644 --- a/tests/behat/navigation_externallinks.feature +++ b/tests/behat/navigation_externallinks.feature @@ -19,9 +19,7 @@ Feature: It opens external links properly. | Test forum | student1 | Forum topic | See moodle.org | Scenario: Click an external link - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Test forum" in the app And I press "Forum topic" in the app And I press "moodle.org" in the app diff --git a/tests/behat/navigation_gestures.feature b/tests/behat/navigation_gestures.feature index 8e83275fe..67deefcb3 100644 --- a/tests/behat/navigation_gestures.feature +++ b/tests/behat/navigation_gestures.feature @@ -21,9 +21,7 @@ Feature: It navigates using gestures. | student3 | C1 | student | Scenario: Swipe between participants - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Participants" in the app And I press "Student First" in the app And I swipe to the left in the app @@ -42,9 +40,7 @@ Feature: It navigates using gestures. Then I should find "Student First" in the app Scenario: Swipe between filtered participants - When I enter the app - And I log in as "student1" - And I enter the course "Course 1" in the app + When I enter the course "Course 1" as "student1" in the app And I press "Participants" in the app And I press "Search" in the app And I set the field "Search" to "student" in the app From 5b6baee1aeb1072ddfb0ecbd82b611396187766f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 10 Jan 2022 14:18:10 +0100 Subject: [PATCH 169/220] MOBILE-3833 swipe: Change swipe to directive --- tests/behat/app_behat_runtime.js | 6 +++--- tests/behat/behat_app.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index a9c3df3cf..1567ac68a 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -734,8 +734,8 @@ * @param {string} className Constructor class name * @return {object} Component instance */ - const behatGetComponentInstance = function(selector, className) { - log('Action - Get component instance ' + selector + ', ' + className); + const behatGetAngularInstance = function(selector, className) { + log('Action - Get Angular instance ' + selector + ', ' + className); const activeElement = Array.from(document.querySelectorAll(`.ion-page:not(.ion-page-hidden) ${selector}`)).pop(); @@ -757,6 +757,6 @@ press : behatPress, setField : behatSetField, getHeader : behatGetHeader, - getComponentInstance: behatGetComponentInstance, + getAngularInstance: behatGetAngularInstance, }; })(); diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 051e8560b..d36f1f405 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -237,7 +237,7 @@ class behat_app extends behat_base { public function i_swipe_in_the_app(string $direction) { $method = 'swipe' . ucwords($direction); - $this->evaluate_script("behat.getComponentInstance('core-swipe-navigation', 'CoreSwipeNavigationComponent').$method()"); + $this->evaluate_script("behat.getAngularInstance('ion-content', 'CoreSwipeNavigationDirective').$method()"); } /** From 21230f733fb142539058d65917a7d2e1ee1b2172 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 12 Jan 2022 16:34:55 +0100 Subject: [PATCH 170/220] MOBILE-3833 settings: Test navigation --- tests/behat/settings_navigation.feature | 82 +++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 tests/behat/settings_navigation.feature diff --git a/tests/behat/settings_navigation.feature b/tests/behat/settings_navigation.feature new file mode 100644 index 000000000..2837c1171 --- /dev/null +++ b/tests/behat/settings_navigation.feature @@ -0,0 +1,82 @@ +@app @javascript +Feature: It navigates properly within settings. + + Background: + Given the following "users" exist: + | username | + | student1 | + + Scenario: Mobile navigation + Given I enter the app + And I log in as "student1" + + # Settings + When I press "More" in the app + And I press "App settings" in the app + Then I should find "General" in the app + And I should find "Space usage" in the app + And I should find "Synchronisation" in the app + And I should find "About" in the app + + # Settings details + When I press "General" in the app + Then I should find "Language" in the app + And I should find "Text size" in the app + + When I press the back button in the app + And I press "About" in the app + Then I should find "Moodle Mobile" in the app + And I should find "Privacy policy" in the app + + # Preferences + When I press the back button in the app + And I press the back button in the app + And I press the user menu button in the app + And I press "Preferences" in the app + Then I should find "Messages" in the app + And I should find "Notifications" in the app + And I should find "Space usage" in the app + + # Preferences details + When I press "Messages" in the app + Then I should find "Accept messages from" in the app + And I should find "Notification preferences" in the app + + When I press the back button in the app + And I press "Manage storage" in the app + Then I should find "File storage used" in the app + + Scenario: Tablet navigation + Given I enter the app + And I log in as "student1" + And I change viewport size to "1200x640" + + # Settings + When I press "More" in the app + And I press "App settings" in the app + Then I should find "General" in the app + And I should find "Space usage" in the app + And I should find "Synchronisation" in the app + And I should find "About" in the app + And "General" should be selected in the app + And I should find "Language" in the app + And I should find "Text size" in the app + + When I press "About" in the app + Then "About" should be selected in the app + And I should find "Moodle Mobile" in the app + And I should find "Privacy policy" in the app + + # Preferences + When I press the user menu button in the app + And I press "Preferences" in the app + Then I should find "Messages" in the app + And I should find "Notifications" in the app + And I should find "Space usage" in the app + And "Messages" should be selected in the app + And I should find "Accept messages from" in the app + And I should find "Notification preferences" in the app + + When I press "Manage storage" in the app + Then "Manage storage" should be selected in the app + And I should find "File storage used" in the app From e37011b0de625872713fe73ff2cb0af6b08aa175 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Thu, 13 Jan 2022 13:20:52 +0100 Subject: [PATCH 171/220] MOBILE-3922 mainmenu: Test that the right page is loaded --- tests/behat/mainmenu.feature | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/behat/mainmenu.feature diff --git a/tests/behat/mainmenu.feature b/tests/behat/mainmenu.feature new file mode 100644 index 000000000..421062ab2 --- /dev/null +++ b/tests/behat/mainmenu.feature @@ -0,0 +1,42 @@ +@app @javascript +Feature: Main Menu opens the right page + + Background: + Given the following "users" exist: + | username | + | student | + And the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | student | C1 | student | + + Scenario: Opens Site Home when defaulthomepage is set to Site + Given the following config values are set as admin: + | defaulthomepage | 0 | + When I enter the app + And I log in as "student" + Then "Site home" should be selected in the app + And I should find "Available courses" in the app + And "Site home" "text" should appear before "Dashboard" "text" in the ".core-tabs-bar" "css_element" + And "Home" "text" should appear before "My courses" "text" in the ".mainmenu-tabs" "css_element" + + Scenario: Opens Dashboard when defaulthomepage is set to Dashboard + Given the following config values are set as admin: + | defaulthomepage | 1 | + When I enter the app + And I log in as "student" + Then "Dashboard" should be selected in the app + And I should find "Timeline" in the app + And "Dashboard" "text" should appear before "Site home" "text" in the ".core-tabs-bar" "css_element" + And "Home" "text" should appear before "My courses" "text" in the ".mainmenu-tabs" "css_element" + + Scenario: Opens My Courses when defaulthomepage is set to My Courses + Given the following config values are set as admin: + | defaulthomepage | 3 | + When I enter the app + And I log in as "student" + Then "My courses" near "Home" should be selected in the app + And I should find "Course 1" in the app + And "My courses" "text" should appear before "Home" "text" in the ".mainmenu-tabs" "css_element" From bf2ae1ece7294ff0577ccc4678123fc3759ed1f9 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 23 Dec 2021 17:49:20 +0100 Subject: [PATCH 172/220] MOBILE-3934 behat: Implement `within` locator --- tests/behat/app_behat_runtime.js | 40 +++++++++++++++++++++++++++++++- tests/behat/behat_app.php | 8 +++---- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 1567ac68a..03e647250 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -345,6 +345,26 @@ return element.parentElement || (element.getRootNode() && element.getRootNode().host) || null; }; + /** + * Get closest element matching a selector, without traversing up a given container. + * + * @param {HTMLElement} element Element. + * @param {string} selector Selector. + * @param {HTMLElement} container Topmost container to search within. + * @return {HTMLElement} Closest matching element. + */ + const getClosestMatching = function(element, selector, container) { + if (element.matches(selector)) { + return element; + } + + if (element === container || !element.parentElement) { + return null; + } + + return getClosestMatching(element.parentElement, selector, container); + }; + /** * Function to find elements based on their text or Aria label. * @@ -361,6 +381,24 @@ let container = topContainer; + if (locator.within) { + const withinElements = findElementsBasedOnText(locator.within); + + if (withinElements.length === 0) { + throw new Error('There was no match for within text') + } else if (withinElements.length > 1) { + const withinElementsAncestors = getTopAncestors(withinElements); + + if (withinElementsAncestors.length > 1) { + throw new Error('Too many matches for within text'); + } + + topContainer = container = withinElementsAncestors[0]; + } else { + topContainer = container = withinElements[0]; + } + } + if (topContainer && locator.near) { const nearElements = findElementsBasedOnText(locator.near); @@ -382,7 +420,7 @@ do { const elements = findElementsBasedOnTextWithin(container, locator.text); const filteredElements = locator.selector - ? elements.filter(element => element.matches(locator.selector)) + ? elements.map(element => getClosestMatching(element, locator.selector, container)).filter(element => !!element) : elements; if (filteredElements.length > 0) { diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index d36f1f405..3bd63c9f2 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -1020,7 +1020,7 @@ class behat_app extends behat_base { * @return object */ public function parse_element_locator(string $text): object { - preg_match('/^"((?:[^"]|\\")*?)"(?: "([^"]*?)")?(?: near "((?:[^"]|\\")*?)"(?: "([^"]*?)")?)?$/', $text, $matches); + preg_match('/^"((?:[^"]|\\")*?)"(?: "([^"]*?)")?(?: (near|within) "((?:[^"]|\\")*?)"(?: "([^"]*?)")?)?$/', $text, $matches); $locator = [ 'text' => str_replace('\\"', '"', $matches[1]), @@ -1028,9 +1028,9 @@ class behat_app extends behat_base { ]; if (!empty($matches[3])) { - $locator['near'] = (object) [ - 'text' => str_replace('\\"', '"', $matches[3]), - 'selector' => $matches[4] ?? null, + $locator[$matches[3]] = (object) [ + 'text' => str_replace('\\"', '"', $matches[4]), + 'selector' => $matches[5] ?? null, ]; } From 0dceb1ecac6c36e6948701b9fa31fb1e2819d8cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 13 Jan 2022 15:27:30 +0100 Subject: [PATCH 173/220] MOBILE-3954: Prefecth course module moved to manage storage --- .../tests/behat/app_basic_usage.feature | 7 +++--- mod/forum/tests/behat/app_basic_usage.feature | 22 +++++++++++-------- .../tests/behat/app_basic_usage.feature | 3 ++- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index abf5a0c53..abd199c27 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -133,9 +133,10 @@ Feature: Test basic usage of choice activity in app | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | When I enter the course "Course 1" as "student1" in the app And I press "Display options" in the app - And I press "Show download options" in the app - And I press "Download" near "Test single choice name" in the app - Then I should find "Downloaded" near "Test single choice name" in the app + And I press "Manage course storage" in the app + And I press "Download" within "Test single choice name" "ion-item" in the app + Then I should find "Downloaded" within "Test single choice name" "ion-item" in the app + And I press the back button in the app When I switch offline mode to "true" And I press "Test multi choice name" in the app diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 6789902d1..63a4821f6 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -183,8 +183,9 @@ Feature: Test basic usage of forum activity in app When I press the back button in the app And I press "Display options" in the app - And I press "Show download options" in the app - And I press "Download" near "Test forum name" in the app + And I press "Manage course storage" in the app + And I press "Download" within "Test forum name" "ion-item" in the app + And I press the back button in the app And I press "Test forum name" in the app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app Then I should find "Reply" in the app @@ -209,8 +210,9 @@ Feature: Test basic usage of forum activity in app When I press the back button in the app And I press "Display options" in the app - And I press "Show download options" in the app - And I press "Download" near "Test forum name" in the app + And I press "Manage course storage" in the app + And I press "Download" within "Test forum name" "ion-item" in the app + And I press the back button in the app And I press "Test forum name" in the app And I press "Auto-test" near "Sort by last post creation date in descending order" in the app Then I should find "Reply" in the app @@ -287,8 +289,9 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app And I press the back button in the app And I press "Display options" in the app - And I press "Show download options" in the app - And I press "Download" near "Test forum name" in the app + And I press "Manage course storage" in the app + And I press "Download" within "Test forum name" "ion-item" in the app + And I press the back button in the app And I press "Test forum name" in the app And I press "DiscussionSubject" in the app And I switch offline mode to "true" @@ -365,9 +368,10 @@ Feature: Test basic usage of forum activity in app When I press the back button in the app And I press "Display options" in the app - And I press "Show download options" in the app - And I press "Download" near "Test forum name" in the app - Then I should find "Downloaded" near "Test forum name" in the app + And I press "Manage course storage" in the app + And I press "Download" within "Test forum name" "ion-item" in the app + Then I should find "Downloaded" within "Test forum name" "ion-item" in the app + And I press the back button in the app When I press "Test forum name" in the app And I press "Add a new discussion topic" in the app diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index d9744cd6f..fdbc42998 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -375,8 +375,9 @@ Feature: Test basic usage of survey activity in app | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | When I enter the course "Course 1" as "student1" in the app And I press "Display options" in the app - And I press "Show download options" in the app + And I press "Manage course storage" in the app And I press "cloud download" near "Test survey critical incidents" in the app + And I press the back button in the app And I switch offline mode to "true" And I press "Test survey name" in the app Then I should see "There was a problem connecting to the site. Please check your connection and try again." From a67e4356af69530547bebb5466f5453637d1b19a Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 12 Jan 2022 16:35:12 +0100 Subject: [PATCH 174/220] MOBILE-3833 chat: Test navigation --- mod/chat/tests/behat/app_navigation.feature | 44 +++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 mod/chat/tests/behat/app_navigation.feature diff --git a/mod/chat/tests/behat/app_navigation.feature b/mod/chat/tests/behat/app_navigation.feature new file mode 100644 index 000000000..fb4cd37ad --- /dev/null +++ b/mod/chat/tests/behat/app_navigation.feature @@ -0,0 +1,44 @@ +@mod @mod_chat @app @javascript +Feature: Test chat navigation + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "users" exist: + | username | firstname | lastname | + | student1 | Student | first | + | student2 | Student | second | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | student2 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | chat | Test chat name | Test chat | C1 | chat | 0 | + # Create sessions + # TODO use generator instead + And I enter the course "Course 1" as "student1" in the app + And I press "Test chat name" in the app + And I press "Enter the chat" in the app + And I set the field "New message" to "Test message" in the app + And I press "Send" in the app + Then I should find "Test message" in the app + + Scenario: Tablet navigation + Given I enter the course "Course 1" as "student2" in the app + And I change viewport size to "1200x640" + + # Sessions + When I press "Test chat name" in the app + And I press "View past chat sessions" in the app + Then I should find "No sessions found" in the app + + # Sessions — split view + When I press "Show incomplete sessions" in the app + Then "Student first" should be selected in the app + And I should find "Test message" in the app + + When I press "Show incomplete sessions" in the app + Then I should not find "Student first" in the app + And I should not find "Test message" in the app From e8aaf2c1584e8547eed851f8f9f9f21042e1a4e7 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 25 Jan 2022 17:36:36 +0100 Subject: [PATCH 175/220] MOBILE-3833 behat: Update strings --- mod/chat/tests/behat/app_basic_usage.feature | 12 +++---- mod/chat/tests/behat/app_navigation.feature | 2 +- .../tests/behat/app_basic_usage.feature | 6 ++-- mod/forum/tests/behat/app_basic_usage.feature | 34 +++++++++---------- mod/forum/tests/behat/app_navigation.feature | 8 ++--- mod/login/tests/behat/app_basic_usage.feature | 4 +-- tests/behat/app_behat_runtime.js | 2 +- tests/behat/navigation_deeplinks.feature | 2 +- 8 files changed, 35 insertions(+), 35 deletions(-) diff --git a/mod/chat/tests/behat/app_basic_usage.feature b/mod/chat/tests/behat/app_basic_usage.feature index f3727631f..ef4f1d2da 100755 --- a/mod/chat/tests/behat/app_basic_usage.feature +++ b/mod/chat/tests/behat/app_basic_usage.feature @@ -23,10 +23,10 @@ Feature: Test basic usage of chat in app # Send messages as student1 When I enter the course "Course 1" as "student1" in the app And I press "Test chat name" in the app - Then I should find "Click here to enter the chat now" in the app - And I should find "View past chat sessions" in the app + Then I should find "Enter the chat" in the app + And I should find "Past sessions" in the app - When I press "Click here to enter the chat now" in the app + When I press "Enter the chat" in the app And I set the field "New message" to "Hi!" in the app And I press "Send" in the app Then I should find "Hi!" in the app @@ -39,7 +39,7 @@ Feature: Test basic usage of chat in app # Read messages, view connected users, send beep and reply as student2 When I enter the course "Course 1" as "student2" in the app And I press "Test chat name" in the app - And I press "Click here to enter the chat now" in the app + And I press "Enter the chat" in the app Then I should find "Hi!" in the app And I should find "I am David" in the app @@ -57,7 +57,7 @@ Feature: Test basic usage of chat in app # Send messages as student1 Given I enter the course "Course 1" as "student1" in the app And I press "Test chat name" in the app - And I press "Click here to enter the chat now" in the app + And I press "Enter the chat" in the app And I set the field "New message" to "Hi!" in the app And I press "Send" in the app Then I should find "Hi!" in the app @@ -69,7 +69,7 @@ Feature: Test basic usage of chat in app # Read messages from past sessions as student2 When I enter the course "Course 1" as "student2" in the app And I press "Test chat name" in the app - And I press "View past chat sessions" in the app + And I press "Past sessions" in the app And I press "Show incomplete sessions" in the app And I press "david student" near "(2)" in the app Then I should find "Hi!" in the app diff --git a/mod/chat/tests/behat/app_navigation.feature b/mod/chat/tests/behat/app_navigation.feature index fb4cd37ad..eccea87d3 100644 --- a/mod/chat/tests/behat/app_navigation.feature +++ b/mod/chat/tests/behat/app_navigation.feature @@ -31,7 +31,7 @@ Feature: Test chat navigation # Sessions When I press "Test chat name" in the app - And I press "View past chat sessions" in the app + And I press "Past sessions" in the app Then I should find "No sessions found" in the app # Sessions — split view diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index a51cec01e..088c511c1 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -419,7 +419,7 @@ Feature: Test basic usage of one course in app And I press "Enrol me" in the app And I press "OK" in the app And I wait loading to finish in the app - And I press "Contents" in the app + And I press "Course" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -453,9 +453,9 @@ Feature: Test basic usage of one course in app And I press "Available courses" in the app And I press "Course 1" in the app Then I should find "Download course" in the app - And I should find "Contents" in the app + And I should find "Course" in the app - When I press "Contents" in the app + When I press "Course" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 63a4821f6..12eaf072d 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -27,7 +27,7 @@ Feature: Test basic usage of forum activity in app Scenario: Create new discussion When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "My happy subject" in the app And I set the field "Message" to "An awesome message" in the app And I press "Post to forum" in the app @@ -39,7 +39,7 @@ Feature: Test basic usage of forum activity in app Scenario: Reply a post When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app @@ -55,11 +55,11 @@ Feature: Test basic usage of forum activity in app Scenario: Star and pin discussions (student) When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "starred subject" in the app And I set the field "Message" to "starred message" in the app And I press "Post to forum" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "normal subject" in the app And I set the field "Message" to "normal message" in the app And I press "Post to forum" in the app @@ -89,15 +89,15 @@ Feature: Test basic usage of forum activity in app Scenario: Star and pin discussions (teacher) When I enter the course "Course 1" as "teacher1" in the app And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test star" in the app And I set the field "Message" to "Auto-test star message" in the app And I press "Post to forum" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test pin" in the app And I set the field "Message" to "Auto-test pin message" in the app And I press "Post to forum" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test plain" in the app And I set the field "Message" to "Auto-test plain message" in the app And I press "Post to forum" in the app @@ -119,7 +119,7 @@ Feature: Test basic usage of forum activity in app Scenario: Edit a not sent reply offline When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -153,7 +153,7 @@ Feature: Test basic usage of forum activity in app When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I switch offline mode to "true" - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -175,7 +175,7 @@ Feature: Test basic usage of forum activity in app Scenario: Edit a forum post (only online) When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -202,7 +202,7 @@ Feature: Test basic usage of forum activity in app Scenario: Delete a forum post (only online) When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -236,7 +236,7 @@ Feature: Test basic usage of forum activity in app Scenario: Add/view ratings Given I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -283,7 +283,7 @@ Feature: Test basic usage of forum activity in app Scenario: Reply a post offline When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app @@ -315,7 +315,7 @@ Feature: Test basic usage of forum activity in app When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I switch offline mode to "true" - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app @@ -338,7 +338,7 @@ Feature: Test basic usage of forum activity in app When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I switch offline mode to "true" - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app @@ -360,7 +360,7 @@ Feature: Test basic usage of forum activity in app Scenario: Prefetch When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject 1" in the app And I set the field "Message" to "DiscussionMessage 1" in the app And I press "Post to forum" in the app @@ -374,7 +374,7 @@ Feature: Test basic usage of forum activity in app And I press the back button in the app When I press "Test forum name" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject 2" in the app And I set the field "Message" to "DiscussionMessage 2" in the app And I press "Post to forum" in the app diff --git a/mod/forum/tests/behat/app_navigation.feature b/mod/forum/tests/behat/app_navigation.feature index 975887b6a..f72b98764 100644 --- a/mod/forum/tests/behat/app_navigation.feature +++ b/mod/forum/tests/behat/app_navigation.feature @@ -102,12 +102,12 @@ Feature: Test forum navigation # Offline When I press the back button in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I switch offline mode to "true" And I set the field "Subject" to "Offline discussion 1" in the app And I set the field "Message" to "Offline discussion 1 message" in the app And I press "Post to forum" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "Offline discussion 2" in the app And I set the field "Message" to "Offline discussion 2 message" in the app And I press "Post to forum" in the app @@ -194,12 +194,12 @@ Feature: Test forum navigation And I should find "Discussion 05 first reply" inside the split-view content in the app # Offline - When I press "Add a new discussion topic" in the app + When I press "Add discussion topic" in the app And I switch offline mode to "true" And I set the field "Subject" to "Offline discussion 1" in the app And I set the field "Message" to "Offline discussion 1 message" in the app And I press "Post to forum" in the app - And I press "Add a new discussion topic" in the app + And I press "Add discussion topic" in the app And I set the field "Subject" to "Offline discussion 2" in the app And I set the field "Message" to "Offline discussion 2 message" in the app And I press "Post to forum" in the app diff --git a/mod/login/tests/behat/app_basic_usage.feature b/mod/login/tests/behat/app_basic_usage.feature index e985ce73f..b94698e0b 100755 --- a/mod/login/tests/behat/app_basic_usage.feature +++ b/mod/login/tests/behat/app_basic_usage.feature @@ -36,7 +36,7 @@ Feature: Test basic usage of login in app And I press the user menu button in the app And I press "Log out" in the app And I wait the app to restart - And I press "Add a new account" in the app + And I press "Add" in the app And I set the field "Your site" to "Wrong Site Address" in the app And I press enter in the app Then I should find "Cannot connect" in the app @@ -47,7 +47,7 @@ Feature: Test basic usage of login in app And I log in as "student1" And I press the user menu button in the app And I press "Switch account" in the app - And I press "Add a new account" in the app + And I press "Add" in the app And I wait the app to restart And I set the field "Your site" to "Wrong Site Address" in the app And I press enter in the app diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 03e647250..fac2f2dd1 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -497,7 +497,7 @@ })[0]; break; case 'user menu' : - foundButton = findElementsBasedOnText({ text: 'Account' })[0]; + foundButton = findElementsBasedOnText({ text: 'User account' })[0]; break; case 'page menu': foundButton = findElementsBasedOnText({ text: 'Display options' })[0]; diff --git a/tests/behat/navigation_deeplinks.feature b/tests/behat/navigation_deeplinks.feature index ef6ac776f..0b7ec9a82 100644 --- a/tests/behat/navigation_deeplinks.feature +++ b/tests/behat/navigation_deeplinks.feature @@ -28,7 +28,7 @@ Feature: It navigates properly using deep links. And I press the user menu button in the app And I press "Log out" in the app And I wait the app to restart - And I press "Add a new account" in the app + And I press "Add" in the app And I set the field "Your site" to "$WWWROOT" in the app And I press "Connect to your site" in the app And I log in as "student1" From a3910f141f73a20de04f200cf8d1715e21911dc6 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 25 Jan 2022 17:37:42 +0100 Subject: [PATCH 176/220] MOBILE-3833 assignment: Update submissions order --- .../tests/behat/app_navigation.feature | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/mod/assignment/tests/behat/app_navigation.feature b/mod/assignment/tests/behat/app_navigation.feature index b765b2a6e..95744dc49 100644 --- a/mod/assignment/tests/behat/app_navigation.feature +++ b/mod/assignment/tests/behat/app_navigation.feature @@ -56,20 +56,20 @@ Feature: Test assignments navigation But I should not find "Second Student" in the app And I should not find "Third Student" in the app + When I swipe to the left in the app + Then I should find "Second Student" in the app + But I should not find "First Student" in the app + And I should not find "Third Student" in the app + When I swipe to the left in the app Then I should find "Third Student" in the app But I should not find "First Student" in the app And I should not find "Second Student" in the app When I swipe to the left in the app - Then I should find "Second Student" in the app + Then I should find "Third Student" in the app But I should not find "First Student" in the app - And I should not find "Third Student" in the app - - When I swipe to the left in the app - Then I should find "Second Student" in the app - But I should not find "First Student" in the app - And I should not find "Third Student" in the app + And I should not find "Second Student" in the app # Drafts When I press the back button in the app @@ -133,21 +133,21 @@ Feature: Test assignments navigation And I should find "Third Student" in the app But I should not find "First Student" in the app - When I press "Third Student" in the app + When I press "Second Student" in the app And I swipe to the right in the app + Then I should find "Second Student" in the app + But I should not find "First Student" in the app + And I should not find "Third Student" in the app + + When I swipe to the left in the app Then I should find "Third Student" in the app But I should not find "First Student" in the app And I should not find "Second Student" in the app When I swipe to the left in the app - Then I should find "Second Student" in the app + Then I should find "Third Student" in the app But I should not find "First Student" in the app - And I should not find "Third Student" in the app - - When I swipe to the left in the app - Then I should find "Second Student" in the app - But I should not find "First Student" in the app - And I should not find "Third Student" in the app + And I should not find "Second Student" in the app Scenario: Tablet navigation Given I enter the course "Course 1" as "teacher1" in the app @@ -212,13 +212,13 @@ Feature: Test assignments navigation And I press "Group 2" in the app Then I should find "Second Student" in the app And I should find "Third Student" in the app - And "Third Student" near "Second Student" should be selected in the app - And I should find "Third Student" inside the split-view content in the app - But I should not find "First Student" in the app - And I should not find "Second Student" inside the split-view content in the app - - When I press "Second Student" in the app - Then "Second Student" near "Third Student" should be selected in the app + And "Second Student" near "Third Student" should be selected in the app And I should find "Second Student" inside the split-view content in the app - But I should not find "Third Student" inside the split-view content in the app + But I should not find "First Student" in the app + And I should not find "Third Student" inside the split-view content in the app + + When I press "Third Student" in the app + Then "Third Student" near "Second Student" should be selected in the app + And I should find "Third Student" inside the split-view content in the app + But I should not find "Second Student" inside the split-view content in the app And I should not find "First Student" in the app From 82fdde048231c28336787743cda2b565d50dccd6 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 25 Jan 2022 17:39:01 +0100 Subject: [PATCH 177/220] MOBILE-3833 behat: Improve loading more items Without using a smooth scroll, the scroll jumps straight to the loader and sometimes it makes tests fail. Using smooth scrolling is closer to what a user would do and it fixes this problem. --- tests/behat/app_behat_runtime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index fac2f2dd1..0f61bcc3c 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -617,7 +617,7 @@ return 'ERROR: All items are already loaded'; } - infiniteLoading.scrollIntoView(); + infiniteLoading.scrollIntoView({ behavior: 'smooth' }); // Wait 100ms await new Promise(resolve => setTimeout(resolve, 100)); From 5a68dc1f16800abdb49b0a38f6edc274a3317e67 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 27 Jan 2022 11:04:26 +0100 Subject: [PATCH 178/220] MOBILE-3833 behat: Fix grades tests --- tests/behat/navigation_splitview.feature | 47 +++++------------------- 1 file changed, 9 insertions(+), 38 deletions(-) diff --git a/tests/behat/navigation_splitview.feature b/tests/behat/navigation_splitview.feature index 7efe86451..3b6e31359 100644 --- a/tests/behat/navigation_splitview.feature +++ b/tests/behat/navigation_splitview.feature @@ -37,20 +37,14 @@ Feature: It navigates properly in pages with a split-view component. # Open C1 course grades When I press "Course 1" in the app - Then the header should be "Grades" in the app + Then the header should be "Course 1" in the app And I should find "Grade category C1" in the app # Open C1 grade item When I press "Grade item C1" in the app - Then the header should be "Grade" in the app - And I should find "20" near "Range" in the app + Then I should find "20" near "Range" in the app And I should find "40" near "Range" in the app - # Go back to course grades - When I press the back button in the app - Then the header should be "Grades" in the app - And I should find "Grade category C1" in the app - # Go back to grades page When I press the back button in the app Then the header should be "Grades" in the app @@ -59,20 +53,14 @@ Feature: It navigates properly in pages with a split-view component. # Open C2 course grades When I press "Course 2" in the app - Then the header should be "Grades" in the app + Then the header should be "Course 2" in the app And I should find "Grade category C2" in the app # Open C2 grade item When I press "Grade item C2" in the app - Then the header should be "Grade" in the app - And I should find "60" near "Range" in the app + Then I should find "60" near "Range" in the app And I should find "80" near "Range" in the app - # Go back to course grades - When I press the back button in the app - Then the header should be "Grades" in the app - And I should find "Grade category C2" in the app - # Go back to grades page When I press the back button in the app Then the header should be "Grades" in the app @@ -82,7 +70,7 @@ Feature: It navigates properly in pages with a split-view component. # Go back to main page When I press the back button in the app Then I should find "Acceptance test site" in the app - And I should find "Account" in the app + And I should find "User account" in the app But I should not find "Back" in the app Scenario: Navigate in grades tab on tablet @@ -102,39 +90,22 @@ Feature: It navigates properly in pages with a split-view component. # Open C1 course grades When I press "Grade item C1" in the app - Then the header should be "Grades" in the app - And I should find "Grade category C1" in the app + Then I should find "Grade category C1" in the app And I should find "20" near "Range" in the app And I should find "40" near "Range" in the app - # Go back to grades page - When I press the back button in the app - Then the header should be "Grades" in the app - And I should find "Course 1" in the app - And I should find "Course 2" in the app - # Select C2 course When I press "Course 2" in the app - Then the header should be "Grades" in the app - And "Course 2" should be selected in the app + Then "Course 2" should be selected in the app And I should find "Grade category C2" in the app # Open C2 course grades When I press "Grade item C2" in the app - Then the header should be "Grades" in the app - And I should find "Grade category C2" in the app - And I should find "60" near "Range" in the app + Then I should find "60" near "Range" in the app And I should find "80" near "Range" in the app - # Go back to grades page - When I press the back button in the app - Then the header should be "Grades" in the app - And I should find "Course 1" in the app - And I should find "Course 2" in the app - And I should find "Back" in the app - # Go back to main page When I press the back button in the app Then I should find "Acceptance test site" in the app - And I should find "Account" in the app + And I should find "User account" in the app But I should not find "Back" in the app From 8c0d9042b2416083f1b0473b46a139cd1371226b Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Mon, 31 Jan 2022 13:12:36 +0100 Subject: [PATCH 179/220] MOBILE-3833 behat: Test custom URL that calls WS when logged out --- tests/behat/behat_app.php | 24 +++++++++++++++++++++--- tests/behat/navigation_deeplinks.feature | 22 +++++++++++++++++++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 3bd63c9f2..e9a1901ad 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -691,9 +691,27 @@ class behat_app extends behat_base { public function i_open_a_custom_link(TableNode $data) { global $DB, $CFG; - $data = (object) $data->getColumnsHash()[0]; - $discussion = $DB->get_record('forum_discussions', ['name' => $data->discussion]); - $pageurl = "{$CFG->behat_wwwroot}/mod/forum/discuss.php?d={$discussion->id}"; + $data = $data->getColumnsHash()[0]; + $title = array_keys($data)[0]; + $data = (object) $data; + + switch ($title) { + case 'discussion': + $discussion = $DB->get_record('forum_discussions', ['name' => $data->discussion]); + $pageurl = "{$CFG->behat_wwwroot}/mod/forum/discuss.php?d={$discussion->id}"; + + break; + + case 'forum': + $forumdata = $DB->get_record('forum', ['name' => $data->forum]); + $cm = get_coursemodule_from_instance('forum', $forumdata->id); + $pageurl = "{$CFG->behat_wwwroot}/mod/forum/view.php?id={$cm->id}"; + break; + + default: + throw new DriverException('Invalid custom link title - ' . $title); + } + $url = "moodlemobile://link=" . urlencode($pageurl); $this->evaluate_script("return window.urlSchemes.handleCustomURL('$url')"); diff --git a/tests/behat/navigation_deeplinks.feature b/tests/behat/navigation_deeplinks.feature index 0b7ec9a82..b59d89794 100644 --- a/tests/behat/navigation_deeplinks.feature +++ b/tests/behat/navigation_deeplinks.feature @@ -20,7 +20,8 @@ Feature: It navigates properly using deep links. | forum | user | name | message | | Test forum | student1 | Forum topic | Forum message | And the following config values are set as admin: - | forcelogout | 1 | tool_mobile | + | forcelogout | 1 | tool_mobile | + | defaulthomepage | 0 | | Scenario: Receive a push notification When I enter the app @@ -64,3 +65,22 @@ Feature: It navigates properly using deep links. Then I should find "Site home" in the app But I should not find "Forum topic" in the app And I should not find "Forum message" in the app + + Scenario: Open a link with a custom URL that calls WebServices for a logged out site + When I enter the app + And I log in as "student2" + And I press the user menu button in the app + And I press "Log out" in the app + And I wait the app to restart + And I open a custom link in the app for: + | forum | + | Test forum | + Then I should find "Reconnect" in the app + + When I set the field "Password" to "student2" in the app + And I press "Log in" in the app + Then I should find "Test forum" in the app + + When I press the back button in the app + Then I should find "Site home" in the app + But I should not find "Test forum" in the app From 95b7bde2a3ef11c4852f34755fa1c3f95211e958 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 31 Jan 2022 14:52:59 +0100 Subject: [PATCH 180/220] MOBILE-3833 course: Fix course navigation --- .../tests/behat/app_basic_usage.feature | 31 +++++++++---------- .../tests/behat/app_basic_usage.feature | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 088c511c1..5ec5bab42 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -164,8 +164,8 @@ Feature: Test basic usage of one course in app And I should find "Test scorm name" in the app And I should find "Test workshop name" in the app - When I press "Section:" in the app - And I press "General" near "Sections" "h2" in the app + When I press "Course index" in the app + And I press "General" in the app Then I should find "Test forum name" in the app And I should find "Test wiki name" in the app But I should not find "Choice course 1" in the app @@ -190,8 +190,8 @@ Feature: Test basic usage of one course in app Then the header should be "Test wiki name" in the app When I press the back button in the app - And I press "Section:" in the app - And I press "Topic 1" near "Sections" "h2" in the app + And I press "Course index" in the app + And I press "Topic 1" in the app Then I should find "Choice course 1" in the app And I should find "assignment" in the app And I should find "Test external name" in the app @@ -223,8 +223,8 @@ Feature: Test basic usage of one course in app Then the header should be "Test survey name" in the app When I press the back button in the app - And I press "Section:" in the app - And I press "Topic 2" near "Sections" "h2" in the app + And I press "Course index" in the app + And I press "Topic 2" in the app Then I should find "Quiz 1" in the app And I should find "Test chat name" in the app And I should find "Test scorm name" in the app @@ -252,8 +252,8 @@ Feature: Test basic usage of one course in app Then the header should be "Test scorm name" in the app When I press the back button in the app - And I press "Section:" in the app - And I press "Topic 3" near "Sections" "h2" in the app + And I press "Course index" in the app + And I press "Topic 3" in the app Then I should find "Test feedback name" in the app And I should find "Test lesson name" in the app And I should find "Test workshop name" in the app @@ -282,8 +282,8 @@ Feature: Test basic usage of one course in app Then the header should be "Test workshop name" in the app When I press the back button in the app - And I press "Section:" in the app - And I press "Topic 4" near "Sections" "h2" in the app + And I press "Course index" in the app + And I press "Topic 4" in the app Then I should find "Web links" in the app But I should not find "Choice course 1" in the app And I should not find "assignment" in the app @@ -303,8 +303,8 @@ Feature: Test basic usage of one course in app Then the header should be "Web links" in the app When I press the back button in the app - And I press "Section:" in the app - And I press "Topic 5" near "Sections" "h2" in the app + And I press "Course index" in the app + And I press "Topic 5" in the app Then I should find "Test glossary" in the app But I should not find "Choice course 1" in the app And I should not find "assignment" in the app @@ -341,8 +341,8 @@ Feature: Test basic usage of one course in app And I should find "Test scorm name" in the app And I should find "Test workshop name" in the app - When I press "Section:" in the app - And I press "General" near "Sections" "h2" in the app + When I press "Course index" in the app + And I press "General" in the app Then I should find "General" in the app And I should find "Next: Topic 1" in the app But I should not find "Topic 2" in the app @@ -419,7 +419,6 @@ Feature: Test basic usage of one course in app And I press "Enrol me" in the app And I press "OK" in the app And I wait loading to finish in the app - And I press "Course" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -455,7 +454,7 @@ Feature: Test basic usage of one course in app Then I should find "Download course" in the app And I should find "Course" in the app - When I press "Course" in the app + When I press "Course" "ion-button" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index 5d142bd06..df69a7f0d 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -88,7 +88,7 @@ Feature: Test basic usage of courses in app When I press "Course 4" in the app Then I should find "Course 4" in the app - And the header should be "Course 4" in the app + And the header should be "Course summary" in the app When I press the back button in the app And I set the field "Search" to "Course" in the app From 02d0a15111107dfa07829b89acb9ce65720e858b Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 31 Jan 2022 14:53:44 +0100 Subject: [PATCH 181/220] MOBILE-3833 forum: Comment flaky test in CI --- mod/forum/tests/behat/app_navigation.feature | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/mod/forum/tests/behat/app_navigation.feature b/mod/forum/tests/behat/app_navigation.feature index f72b98764..f325f9738 100644 --- a/mod/forum/tests/behat/app_navigation.feature +++ b/mod/forum/tests/behat/app_navigation.feature @@ -124,18 +124,19 @@ Feature: Test forum navigation And I should find "Offline discussion 3" in the app But I should not find "Offline discussion 2" in the app - # Offline — Swipe - When I press "Offline discussion 3" in the app - Then I should find "Offline discussion 3 message" in the app + # TODO fix flaky test failing on CI but working locally + # # Offline — Swipe + # When I press "Offline discussion 3" in the app + # Then I should find "Offline discussion 3 message" in the app - When I swipe to the right in the app - Then I should find "Offline discussion 3 message" in the app + # When I swipe to the right in the app + # Then I should find "Offline discussion 3 message" in the app - When I swipe to the left in the app - Then I should find "Offline discussion 1 message" in the app + # When I swipe to the left in the app + # Then I should find "Offline discussion 1 message" in the app - When I swipe to the left in the app - Then I should find "Discussion 20 message" in the app + # When I swipe to the left in the app + # Then I should find "Discussion 20 message" in the app Scenario: Tablet navigation Given I enter the course "Course 1" as "student1" in the app From 1efc0c52b76fd7d701a5be37b93dcb322243a041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Fri, 4 Feb 2022 09:31:57 +0100 Subject: [PATCH 182/220] MOBILE-3954 behat: Adapt changes on storage manager --- mod/choice/tests/behat/app_basic_usage.feature | 2 +- mod/forum/tests/behat/app_basic_usage.feature | 8 ++++---- mod/survey/tests/behat/app_basic_usage.feature | 2 +- tests/behat/settings_navigation.feature | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index abd199c27..2f0fd786d 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -133,7 +133,7 @@ Feature: Test basic usage of choice activity in app | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | When I enter the course "Course 1" as "student1" in the app And I press "Display options" in the app - And I press "Manage course storage" in the app + And I press "Course downloads" in the app And I press "Download" within "Test single choice name" "ion-item" in the app Then I should find "Downloaded" within "Test single choice name" "ion-item" in the app And I press the back button in the app diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 12eaf072d..6e7a2b55d 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -183,7 +183,7 @@ Feature: Test basic usage of forum activity in app When I press the back button in the app And I press "Display options" in the app - And I press "Manage course storage" in the app + And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app And I press the back button in the app And I press "Test forum name" in the app @@ -210,7 +210,7 @@ Feature: Test basic usage of forum activity in app When I press the back button in the app And I press "Display options" in the app - And I press "Manage course storage" in the app + And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app And I press the back button in the app And I press "Test forum name" in the app @@ -289,7 +289,7 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app And I press the back button in the app And I press "Display options" in the app - And I press "Manage course storage" in the app + And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app And I press the back button in the app And I press "Test forum name" in the app @@ -368,7 +368,7 @@ Feature: Test basic usage of forum activity in app When I press the back button in the app And I press "Display options" in the app - And I press "Manage course storage" in the app + And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app Then I should find "Downloaded" within "Test forum name" "ion-item" in the app And I press the back button in the app diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/mod/survey/tests/behat/app_basic_usage.feature index fdbc42998..09a72b533 100755 --- a/mod/survey/tests/behat/app_basic_usage.feature +++ b/mod/survey/tests/behat/app_basic_usage.feature @@ -375,7 +375,7 @@ Feature: Test basic usage of survey activity in app | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | When I enter the course "Course 1" as "student1" in the app And I press "Display options" in the app - And I press "Manage course storage" in the app + And I press "Course downloads" in the app And I press "cloud download" near "Test survey critical incidents" in the app And I press the back button in the app And I switch offline mode to "true" diff --git a/tests/behat/settings_navigation.feature b/tests/behat/settings_navigation.feature index 2837c1171..fea11957a 100644 --- a/tests/behat/settings_navigation.feature +++ b/tests/behat/settings_navigation.feature @@ -35,7 +35,7 @@ Feature: It navigates properly within settings. And I press "Preferences" in the app Then I should find "Messages" in the app And I should find "Notifications" in the app - And I should find "Space usage" in the app + And I should find "Manage downloads" in the app # Preferences details When I press "Messages" in the app @@ -72,7 +72,7 @@ Feature: It navigates properly within settings. And I press "Preferences" in the app Then I should find "Messages" in the app And I should find "Notifications" in the app - And I should find "Space usage" in the app + And I should find "Manage downloads" in the app And "Messages" should be selected in the app And I should find "Accept messages from" in the app And I should find "Notification preferences" in the app From 00f7cda5bf2c2099aab0a35dcedf024eb2530b5f Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 7 Feb 2022 15:01:41 +0100 Subject: [PATCH 183/220] MOBILE-3954 behat: Update settings strings --- tests/behat/settings_navigation.feature | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/behat/settings_navigation.feature b/tests/behat/settings_navigation.feature index fea11957a..ae4779ae8 100644 --- a/tests/behat/settings_navigation.feature +++ b/tests/behat/settings_navigation.feature @@ -43,8 +43,8 @@ Feature: It navigates properly within settings. And I should find "Notification preferences" in the app When I press the back button in the app - And I press "Manage storage" in the app - Then I should find "File storage used" in the app + And I press "Manage downloads" in the app + Then I should find "Total space usage" in the app Scenario: Tablet navigation Given I enter the app @@ -77,6 +77,6 @@ Feature: It navigates properly within settings. And I should find "Accept messages from" in the app And I should find "Notification preferences" in the app - When I press "Manage storage" in the app - Then "Manage storage" should be selected in the app - And I should find "File storage used" in the app + When I press "Manage downloads" in the app + Then "Manage downloads" should be selected in the app + And I should find "Total space usage" in the app From 77c5418f0c3faeb00875b3d999d4bb21c8f7c835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 22 Feb 2022 13:45:37 +0100 Subject: [PATCH 184/220] Improve location of elements and containers --- tests/behat/app_behat_runtime.js | 119 +++++++++++++++++++++++++------ tests/behat/behat_app.php | 16 +++-- 2 files changed, 109 insertions(+), 26 deletions(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 0f61bcc3c..7d04487c1 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -224,13 +224,13 @@ }; /** - * Finds elements within a given container. + * Finds elements within a given container with exact info. * * @param {HTMLElement} container Parent element to search the element within * @param {string} text Text to look for - * @return {HTMLElement} Elements containing the given text + * @return {Array} Elements containing the given text with exact boolean. */ - const findElementsBasedOnTextWithin = (container, text) => { + const findElementsBasedOnTextWithinWithExact = (container, text) => { const elements = []; const attributesSelector = `[aria-label*="${text}"], a[title*="${text}"], img[alt*="${text}"]`; @@ -238,7 +238,8 @@ if (!isElementVisible(foundByAttributes, container)) continue; - elements.push(foundByAttributes); + const exact = foundByAttributes.title == text || foundByAttributes.alt == text || foundByAttributes.ariaLabel == text; + elements.push({ element: foundByAttributes, exact: exact }); } const treeWalker = document.createTreeWalker( @@ -269,7 +270,7 @@ while (currentNode = treeWalker.nextNode()) { if (currentNode instanceof Text) { if (currentNode.textContent.includes(text)) { - elements.push(currentNode.parentElement); + elements.push({ element: currentNode.parentElement, exact: currentNode.textContent.trim() == text }); } continue; @@ -278,7 +279,7 @@ const labelledBy = currentNode.getAttribute('aria-labelledby'); const labelElement = labelledBy && container.querySelector(`#${labelledBy}`); if (labelElement && labelElement.innerText && labelElement.innerText.includes(text)) { - elements.push(currentNode); + elements.push({ element: currentNode, exact: labelElement.innerText.trim() == text }); continue; } @@ -296,12 +297,13 @@ } if (childNode.matches(attributesSelector)) { - elements.push(childNode); + const exact = childNode.title == text || childNode.alt == text || childNode.ariaLabel == text; + elements.push({ element: childNode, exact: exact}); continue; } - elements.push(...findElementsBasedOnTextWithin(childNode, text)); + elements.push(...findElementsBasedOnTextWithinWithExact(childNode, text)); } } } @@ -309,6 +311,24 @@ return elements; }; + /** + * Finds elements within a given container. + * + * @param {HTMLElement} container Parent element to search the element within. + * @param {string} text Text to look for. + * @return {HTMLElement[]} Elements containing the given text. + */ + const findElementsBasedOnTextWithin = (container, text) => { + const elements = findElementsBasedOnTextWithinWithExact(container, text); + + // Give more relevance to exact matches. + elements.sort((a, b) => { + return b.exact - a.exact; + }); + + return elements.map(element => element.element); + }; + /** * Given a list of elements, get the top ancestors among all of them. * @@ -365,19 +385,78 @@ return getClosestMatching(element.parentElement, selector, container); }; + /** + * Function to find top container element. + * + * @param {string} containerName Whether to search inside the a container name. + * @return {HTMLElement} Found top container element. + */ + const getCurrentTopContainerElement = function (containerName) { + let topContainer; + let containers; + + switch (containerName) { + case 'html': + containers = document.querySelectorAll('html'); + break; + case 'toast': + containers = document.querySelectorAll('ion-app ion-toast.hydrated'); + containers = Array.from(containers).map(container => container.shadowRoot.querySelector('.toast-container')); + break; + case 'alert': + containers = document.querySelectorAll('ion-app ion-alert.hydrated'); + break; + case 'action-sheet': + containers = document.querySelectorAll('ion-app ion-action-sheet.hydrated'); + break; + case 'modal': + containers = document.querySelectorAll('ion-app ion-modal.hydrated'); + break; + case 'popover': + containers = document.querySelectorAll('ion-app ion-popover.hydrated'); + break; + default: + // Other containerName or not implemented. + const containerSelector = 'ion-alert, ion-popover, ion-action-sheet, ion-modal, page-core-mainmenu, ion-app'; + containers = document.querySelectorAll(containerSelector); + } + + if (containers.length > 0) { + // Get the one with more zIndex. + topContainer = Array.from(containers).reduce((a, b) => { + return getComputedStyle(a).zIndex > getComputedStyle(b).zIndex ? a : b; + }, containers[0]); + } + + if (containerName == 'page' || containerName == 'split-view content') { + // Find non hidden pages inside the container. + let pageContainers = topContainer.querySelectorAll('.ion-page:not(.ion-page-hidden)'); + pageContainers = Array.from(pageContainers).filter((page) => { + return !page.closest('.ion-page.ion-page-hidden'); + }); + + if (pageContainers.length > 0) { + // Get the more general one to avoid failing. + topContainer = pageContainers[0]; + } + + if (containerName == 'split-view content') { + topContainer = topContainer.querySelector('core-split-view ion-router-outlet'); + } + } + + return topContainer; + } + /** * Function to find elements based on their text or Aria label. * * @param {object} locator Element locator. - * @param {boolean} insideSplitView Whether to search only inside the split view contents. + * @param {string} containerName Whether to search only inside a specific container. * @return {HTMLElement} Found elements */ - const findElementsBasedOnText = function(locator, insideSplitView) { - let topContainer = document.querySelector('ion-alert, ion-popover, ion-action-sheet, core-ion-tab.show-tab ion-page.show-page, ion-page.show-page, html'); - - if (insideSplitView) { - topContainer = topContainer.querySelector('core-split-view ion-router-outlet'); - } + const findElementsBasedOnText = function(locator, containerName) { + let topContainer = getCurrentTopContainerElement(containerName); let container = topContainer; @@ -544,20 +623,20 @@ * Function to find an arbitrary element based on its text or aria label. * * @param {object} locator Element locator. - * @param {boolean} insideSplitView Whether to search only inside the split view contents. + * @param {string} containerName Whether to search only inside a specific container content. * @return {string} OK if successful, or ERROR: followed by message */ - const behatFind = function(locator, insideSplitView) { - log('Action - Find', { locator, insideSplitView }); + const behatFind = function(locator, containerName) { + log('Action - Find', { locator, containerName }); try { - const element = findElementsBasedOnText(locator, insideSplitView)[0]; + const element = findElementsBasedOnText(locator, containerName)[0]; if (!element) { return 'ERROR: No matches for text'; } - log('Action - Found', { locator, insideSplitView, element }); + log('Action - Found', { locator, containerName, element }); return 'OK'; } catch (error) { return 'ERROR: ' + error.message; diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index e9a1901ad..d056fc1be 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -154,18 +154,22 @@ class behat_app extends behat_base { /** * Finds elements in the app. * - * @Then /^I should( not)? find (".+")( inside the split-view content)? in the app$/ + * @Then /^I should( not)? find (".+")( inside the .+)? in the app$/ * @param bool $not * @param string $locator - * @param bool $insidesplitview + * @param string $containerName */ - public function i_find_in_the_app(bool $not, string $locator, bool $insidesplitview = false) { + public function i_find_in_the_app(bool $not, string $locator, string $containerName = '') { $locator = $this->parse_element_locator($locator); $locatorjson = json_encode($locator); - $insidesplitviewjson = json_encode($insidesplitview); + if (!empty($containerName)) { + preg_match('/^ inside the (.+)$/', $containerName, $matches); + $containerName = $matches[1]; + } + $containerName = json_encode($containerName); - $this->spin(function() use ($not, $locatorjson, $insidesplitviewjson) { - $result = $this->evaluate_script("return window.behat.find($locatorjson, $insidesplitviewjson);"); + $this->spin(function() use ($not, $locatorjson, $containerName) { + $result = $this->evaluate_script("return window.behat.find($locatorjson, $containerName);"); if ($not && $result === 'OK') { throw new DriverException('Error, found an item that should not be found'); From 338258a4adcfdc63e20cef178bde232769f67baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 22 Feb 2022 11:00:18 +0100 Subject: [PATCH 185/220] Fix broken behat tests --- .../tests/behat/app_basic_usage.feature | 2 +- mod/choice/tests/behat/app_basic_usage.feature | 6 +++--- mod/course/tests/behat/app_basic_usage.feature | 4 +--- mod/courses/tests/behat/app_basic_usage.feature | 5 ++--- mod/forum/tests/behat/app_basic_usage.feature | 16 ++++++++-------- mod/quiz/tests/behat/app_basic_usage.feature | 2 +- tests/behat/navigation_externallinks.feature | 3 ++- tests/behat/settings_navigation.feature | 4 ++-- 8 files changed, 20 insertions(+), 22 deletions(-) diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/mod/assignment/tests/behat/app_basic_usage.feature index e3b536b98..1b084985a 100755 --- a/mod/assignment/tests/behat/app_basic_usage.feature +++ b/mod/assignment/tests/behat/app_basic_usage.feature @@ -120,7 +120,7 @@ Feature: Test basic usage of assignment activity in app When I switch offline mode to "false" And I press the back button in the app And I press "assignment1" in the app - And I press "Display options" in the app + And I press "Information" in the app And I press "Refresh" in the app Then I should find "Submitted for grading" in the app But I should not find "This Assignment has offline data to be synchronised." in the app diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index 2f0fd786d..a51feb430 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -93,7 +93,7 @@ Feature: Test basic usage of choice activity in app And I press "Test single choice name" in the app Then I should find "Test single choice description" in the app - When I press "Display options" in the app + When I press "Information" in the app And I press "Refresh" in the app Then I should find "Option 1: 0" in the app And I should find "Option 2: 1" in the app @@ -132,7 +132,7 @@ Feature: Test basic usage of choice activity in app | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | When I enter the course "Course 1" as "student1" in the app - And I press "Display options" in the app + And I press "Course summary" in the app And I press "Course downloads" in the app And I press "Download" within "Test single choice name" "ion-item" in the app Then I should find "Downloaded" within "Test single choice name" "ion-item" in the app @@ -182,7 +182,7 @@ Feature: Test basic usage of choice activity in app And I press "Choice name" in the app Then I should find "Test choice description" in the app - When I press "Display options" in the app + When I press "Information" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 5ec5bab42..885796a8a 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -402,7 +402,6 @@ Feature: Test basic usage of one course in app Scenario: Self enrol Given I enter the course "Course 1" as "teacher1" in the app - And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -437,7 +436,6 @@ Feature: Test basic usage of one course in app Scenario: Guest access Given I enter the course "Course 1" as "teacher1" in the app - And I press "Display options" in the app And I press "Course summary" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -451,7 +449,7 @@ Feature: Test basic usage of one course in app And I press "Site home" in the app And I press "Available courses" in the app And I press "Course 1" in the app - Then I should find "Download course" in the app + Then I should find "Course downloads" in the app And I should find "Course" in the app When I press "Course" "ion-button" in the app diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index df69a7f0d..7c3ea7d4f 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -103,12 +103,11 @@ Feature: Test basic usage of courses in app # Configure assignment as teacher When I enter the course "Course 1" as "teacher1" in the app And I press "assignment" in the app - And I press "Display options" in the app + And I press "Information" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" - And I press "Actions menu" - And I follow "Settings" + And I navigate to "Settings" in current page administration And I press "Expand all" And I click on "duedate[enabled]" "checkbox" And I click on "gradingduedate[enabled]" "checkbox" diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 6e7a2b55d..032b16fd2 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -182,7 +182,7 @@ Feature: Test basic usage of forum activity in app Then I should find "Auto-test" in the app When I press the back button in the app - And I press "Display options" in the app + And I press "Course summary" in the app And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app And I press the back button in the app @@ -209,7 +209,7 @@ Feature: Test basic usage of forum activity in app Then I should find "Auto-test" in the app When I press the back button in the app - And I press "Display options" in the app + And I press "Course summary" in the app And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app And I press the back button in the app @@ -256,7 +256,7 @@ Feature: Test basic usage of forum activity in app And I switch offline mode to "true" And I press "None" near "test2" in the app And I press "0" near "Cancel" in the app - Then I should find "Data stored in the device because it couldn't be sent. It will be sent automatically later." in the app + Then I should find "Data stored in the device because it couldn't be sent. It will be sent automatically later." inside the toast in the app And I should find "Average of ratings: -" in the app And I should find "Average of ratings: 1" in the app @@ -264,7 +264,7 @@ Feature: Test basic usage of forum activity in app And I press the back button in the app Then I should find "This Forum has offline data to be synchronised." in the app - When I press "Display options" near "Test forum name" in the app + When I press "Information" near "Test forum name" in the app And I press "Synchronise now" in the app Then I should not find "This Forum has offline data to be synchronised." in the app @@ -288,7 +288,7 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app And I press the back button in the app - And I press "Display options" in the app + And I press "Course summary" in the app And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app And I press the back button in the app @@ -326,8 +326,8 @@ Feature: Test basic usage of forum activity in app When I switch offline mode to "false" And I press the back button in the app And I press "Test forum name" in the app - And I press "Display options" near "Test forum name" in the app - And I press "Refresh discussions" in the app + And I press "Information" near "Test forum name" in the app + And I press "Refresh" in the app And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app Then I should find "DiscussionSubject" in the app And I should find "DiscussionMessage" in the app @@ -367,7 +367,7 @@ Feature: Test basic usage of forum activity in app Then I should find "DiscussionSubject 1" in the app When I press the back button in the app - And I press "Display options" in the app + And I press "Course summary" in the app And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app Then I should find "Downloaded" within "Test forum name" "ion-item" in the app diff --git a/mod/quiz/tests/behat/app_basic_usage.feature b/mod/quiz/tests/behat/app_basic_usage.feature index 493b7acf0..f9f654800 100755 --- a/mod/quiz/tests/behat/app_basic_usage.feature +++ b/mod/quiz/tests/behat/app_basic_usage.feature @@ -156,7 +156,7 @@ Feature: Attempt a quiz in app When I enter the course "Course 1" as "teacher1" in the app And I press "Quiz 1" in the app - And I press "Display options" in the app + And I press "Information" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" diff --git a/tests/behat/navigation_externallinks.feature b/tests/behat/navigation_externallinks.feature index febd346b5..4abf963fe 100644 --- a/tests/behat/navigation_externallinks.feature +++ b/tests/behat/navigation_externallinks.feature @@ -32,11 +32,12 @@ Feature: It opens external links properly. When I close the browser tab opened by the app And I press the back button in the app - And I press the page menu button in the app + And I press "Information" in the app And I press "Open in browser" in the app Then the app should have opened a browser tab When I close the browser tab opened by the app + When I close the popup in the app And I press "Forum topic" in the app And I press "moodle.org" in the app And I select "Don't show again." in the app diff --git a/tests/behat/settings_navigation.feature b/tests/behat/settings_navigation.feature index ae4779ae8..d5cc521e2 100644 --- a/tests/behat/settings_navigation.feature +++ b/tests/behat/settings_navigation.feature @@ -44,7 +44,7 @@ Feature: It navigates properly within settings. When I press the back button in the app And I press "Manage downloads" in the app - Then I should find "Total space usage" in the app + Then I should find "Total space used" in the app Scenario: Tablet navigation Given I enter the app @@ -79,4 +79,4 @@ Feature: It navigates properly within settings. When I press "Manage downloads" in the app Then "Manage downloads" should be selected in the app - And I should find "Total space usage" in the app + And I should find "Total space used" in the app From ecaaba732a98f378d82c7bbfc9a6d0e0f373b8dc Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Mar 2022 11:16:37 +0100 Subject: [PATCH 186/220] MOBILE-3833 behat: Improve runtime debugging Injecting the runtime instead of evaluating makes it possible to debug using dev tools --- tests/behat/behat_app.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index d056fc1be..f9e1b05a1 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -504,8 +504,14 @@ class behat_app extends behat_base { throw new DriverException('Moodle app not found in browser'); }, false, 60); - // Run the scripts to install Moodle 'pending' checks. - $this->execute_script(file_get_contents(__DIR__ . '/app_behat_runtime.js')); + // Inject Behat JavaScript runtime. + global $CFG; + + $this->execute_script(" + var script = document.createElement('script'); + script.src = '{$CFG->behat_wwwroot}/local/moodlemobileapp/tests/behat/app_behat_runtime.js'; + document.body.append(script); + "); if ($restart) { // Assert initial page. From bf8a8531ecd08c75b6f9e66122bda781aa2ffed3 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Mar 2022 11:17:19 +0100 Subject: [PATCH 187/220] MOBILE-3833 behat: Wait swipe animations to finish This is necessary in order to avoid multiple gestures conflicting with each other. --- tests/behat/behat_app.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index f9e1b05a1..603e298d2 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -242,6 +242,9 @@ class behat_app extends behat_base { $method = 'swipe' . ucwords($direction); $this->evaluate_script("behat.getAngularInstance('ion-content', 'CoreSwipeNavigationDirective').$method()"); + + // Wait swipe animation to finish. + $this->getSession()->wait(300); } /** From 71f1ab5229ee45feae5ff69b47d36e64c988f60b Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Mar 2022 11:18:59 +0100 Subject: [PATCH 188/220] MOBILE-3833 behat: Update course summary steps --- mod/choice/tests/behat/app_basic_usage.feature | 1 - mod/course/tests/behat/app_basic_usage.feature | 3 ++- mod/forum/tests/behat/app_basic_usage.feature | 8 ++------ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/mod/choice/tests/behat/app_basic_usage.feature index a51feb430..5de9ffaf8 100755 --- a/mod/choice/tests/behat/app_basic_usage.feature +++ b/mod/choice/tests/behat/app_basic_usage.feature @@ -132,7 +132,6 @@ Feature: Test basic usage of choice activity in app | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | When I enter the course "Course 1" as "student1" in the app - And I press "Course summary" in the app And I press "Course downloads" in the app And I press "Download" within "Test single choice name" "ion-item" in the app Then I should find "Downloaded" within "Test single choice name" "ion-item" in the app diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 885796a8a..2caa3442f 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -449,7 +449,8 @@ Feature: Test basic usage of one course in app And I press "Site home" in the app And I press "Available courses" in the app And I press "Course 1" in the app - Then I should find "Course downloads" in the app + + Then I should find "Course summary" in the app And I should find "Course" in the app When I press "Course" "ion-button" in the app diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 032b16fd2..6d59c7db0 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -182,7 +182,6 @@ Feature: Test basic usage of forum activity in app Then I should find "Auto-test" in the app When I press the back button in the app - And I press "Course summary" in the app And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app And I press the back button in the app @@ -209,7 +208,6 @@ Feature: Test basic usage of forum activity in app Then I should find "Auto-test" in the app When I press the back button in the app - And I press "Course summary" in the app And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app And I press the back button in the app @@ -264,7 +262,7 @@ Feature: Test basic usage of forum activity in app And I press the back button in the app Then I should find "This Forum has offline data to be synchronised." in the app - When I press "Information" near "Test forum name" in the app + When I press "Information" in the app And I press "Synchronise now" in the app Then I should not find "This Forum has offline data to be synchronised." in the app @@ -288,7 +286,6 @@ Feature: Test basic usage of forum activity in app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app And I press the back button in the app - And I press "Course summary" in the app And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app And I press the back button in the app @@ -326,7 +323,7 @@ Feature: Test basic usage of forum activity in app When I switch offline mode to "false" And I press the back button in the app And I press "Test forum name" in the app - And I press "Information" near "Test forum name" in the app + And I press "Information" in the app And I press "Refresh" in the app And I press "DiscussionSubject" near "Sort by last post creation date in descending order" in the app Then I should find "DiscussionSubject" in the app @@ -367,7 +364,6 @@ Feature: Test basic usage of forum activity in app Then I should find "DiscussionSubject 1" in the app When I press the back button in the app - And I press "Course summary" in the app And I press "Course downloads" in the app And I press "Download" within "Test forum name" "ion-item" in the app Then I should find "Downloaded" within "Test forum name" "ion-item" in the app From bb269382be80814e72fcbc0bdd16aa3d8707ddeb Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Mar 2022 11:19:27 +0100 Subject: [PATCH 189/220] MOBILE-3833 behat: Update quiz steps --- mod/quiz/tests/behat/app_basic_usage.feature | 26 ++++---- .../tests/behat/app_quiz_navigation.feature | 59 +++++++++++-------- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/mod/quiz/tests/behat/app_basic_usage.feature b/mod/quiz/tests/behat/app_basic_usage.feature index f9f654800..4a5e94ba5 100755 --- a/mod/quiz/tests/behat/app_basic_usage.feature +++ b/mod/quiz/tests/behat/app_basic_usage.feature @@ -79,14 +79,14 @@ Feature: Attempt a quiz in app But I should not find "Text of the second question" in the app When I press "Next" near "Question 1" in the app - And I press "Next" near "Quiz 1" in the app + And I press "Submit" near "Quiz 1" in the app Then I should find "Summary of attempt" in the app - When I press "Return to attempt" in the app + When I press "Not yet answered" within "2" "ion-item" in the app Then I should find "Text of the second question" in the app But I should not find "Text of the first question" in the app - When I press "Next" in the app + When I press "Submit" in the app And I press "Submit all and finish" in the app Then I should find "Once you submit" in the app @@ -95,7 +95,7 @@ Feature: Attempt a quiz in app When I press "Submit all and finish" in the app And I press "OK" near "Once you submit" in the app - Then I should find "Review of attempt 1" in the app + Then I should find "Review" in the app And I should find "Started on" in the app And I should find "State" in the app And I should find "Completed on" in the app @@ -111,11 +111,11 @@ Feature: Attempt a quiz in app And I press "Attempt quiz now" in the app And I press "Four" in the app And I press "Three" in the app - And I press "Next" "ion-button" near "Quiz 2" in the app + And I press "Next" near "Quiz 2" in the app And I set the field "Answer" to "testing" in the app - And I press "Next" "ion-button" near "Question 2" in the app + And I press "Next" near "Question 2" in the app And I set the field "Answer" to "5" in the app - And I press "Next" "ion-button" near "Question 3" in the app + And I press "Next" near "Question 3" in the app And I set the field "Answer" to "Testing an essay" in the app And I press "Next" "ion-button" near "Question 4" in the app And I press "quick" ".drag" in the app @@ -124,21 +124,21 @@ Feature: Attempt a quiz in app And I press "" ".place2.drop" in the app And I press "lazy" ".drag" in the app And I press "" ".place3.drop" in the app - And I press "Next" "ion-button" near "Question 5" in the app + And I press "Next" near "Question 5" in the app And I press "True" in the app - And I press "Next" "ion-button" near "Question 6" in the app + And I press "Next" near "Question 6" in the app And I press "Choose... , frog" in the app And I press "amphibian" in the app And I press "Choose... , newt" in the app And I press "insect" in the app And I press "Choose... , cat" in the app And I press "mammal" in the app - And I press "Next" "ion-button" near "Question 7" in the app + And I press "Submit" near "Question 7" in the app Then I should not find "Not yet answered" in the app When I press "Submit all and finish" in the app And I press "OK" in the app - Then I should find "Review of attempt 1" in the app + Then I should find "Review" in the app And I should find "Finished" in the app And I should find "Not yet graded" in the app @@ -149,10 +149,10 @@ Feature: Attempt a quiz in app And I press "True" in the app And I press "Next" near "Question 1" in the app And I press "False" in the app - And I press "Next" near "Question 2" in the app + And I press "Submit" near "Question 2" in the app And I press "Submit all and finish" in the app And I press "OK" in the app - Then I should find "Review of attempt 1" in the app + Then I should find "Review" in the app When I enter the course "Course 1" as "teacher1" in the app And I press "Quiz 1" in the app diff --git a/mod/quiz/tests/behat/app_quiz_navigation.feature b/mod/quiz/tests/behat/app_quiz_navigation.feature index 6cd114a3b..cf52af5c2 100644 --- a/mod/quiz/tests/behat/app_quiz_navigation.feature +++ b/mod/quiz/tests/behat/app_quiz_navigation.feature @@ -36,30 +36,39 @@ Feature: Attempt a quiz in app And I press "Quiz 1" in the app And I press "Attempt quiz now" in the app Then I should find "Text of the first question" in the app - And I should not find "Text of the second question" in the app - And I press "Next" near "Question 1" in the app - And I should find "Text of the second question" in the app - And I should not find "Text of the first question" in the app - And I press "Previous" near "Question 2" in the app - And I should not find "Text of the second question" in the app - And I should find "Text of the first question" in the app - And I press "Next" near "Quiz 1" in the app - And I should find "Text of the second question" in the app - And I should not find "Text of the first question" in the app - And I press "Previous" near "Quiz 1" in the app - And I should not find "Text of the second question" in the app - And I should find "Text of the first question" in the app - And I press "Next" near "Question 1" in the app - And I press "Next" near "Quiz 1" in the app - And I should find "Summary of attempt" in the app - And I press "Return to attempt" in the app - And I should find "Text of the second question" in the app - And I should not find "Text of the first question" in the app - And I press "Next" in the app - And I press "Submit all and finish" in the app - And I should find "Once you submit" in the app - And I press "Cancel" near "Once you submit" in the app - And I should find "Summary of attempt" in the app + But I should not find "Text of the second question" in the app + + When I press "Next" near "Question 1" in the app + Then I should find "Text of the second question" in the app + But I should not find "Text of the first question" in the app + + When I press "Previous" near "Question 2" in the app + Then I should find "Text of the first question" in the app + But I should not find "Text of the second question" in the app + + When I press "Next" near "Quiz 1" in the app + Then I should find "Text of the second question" in the app + But I should not find "Text of the first question" in the app + + When I press "Previous" near "Quiz 1" in the app + Then I should find "Text of the first question" in the app + But I should not find "Text of the second question" in the app + + When I press "Next" near "Question 1" in the app + And I press "Submit" in the app + Then I should find "Summary of attempt" in the app + + When I press "Not yet answered" within "2" "ion-item" in the app + Then I should find "Text of the second question" in the app + But I should not find "Text of the first question" in the app + + When I press "Submit" in the app And I press "Submit all and finish" in the app + Then I should find "Once you submit" in the app + + When I press "Cancel" near "Once you submit" in the app + Then I should find "Summary of attempt" in the app + + When I press "Submit all and finish" in the app And I press "OK" near "Once you submit" in the app - And I should find "Review" in the app + Then I should find "Review" in the app From b1c7bb7617c1415962b331286f30ff148a5172b2 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Mar 2022 11:19:43 +0100 Subject: [PATCH 190/220] MOBILE-3833 behat: Fix LMS UI changes --- mod/courses/tests/behat/app_basic_usage.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index 7c3ea7d4f..5cb9f3953 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -108,7 +108,7 @@ Feature: Test basic usage of courses in app And I switch to the browser tab opened by the app And I log in as "teacher1" And I navigate to "Settings" in current page administration - And I press "Expand all" + And I click on "Expand all" "link" And I click on "duedate[enabled]" "checkbox" And I click on "gradingduedate[enabled]" "checkbox" And I press "Save and return to course" From fe2c4474a9acf600de76845f635753c3aa6b6f04 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Mar 2022 15:14:44 +0100 Subject: [PATCH 191/220] MOBILE-3833 behat: Wait for scroll before click --- tests/behat/app_behat_runtime.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 7d04487c1..baab56f95 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -515,12 +515,20 @@ * * @param {HTMLElement} element Element to press. */ - const pressElement = function(element) { + const pressElement = async function(element) { // Scroll the item into view. + const initialRect = element.getBoundingClientRect(); + element.scrollIntoView(false); + await new Promise(resolve => requestAnimationFrame(resolve)); + const rect = element.getBoundingClientRect(); + if (initialRect.y !== rect.y) { + await new Promise(resolve => setTimeout(resolve, 300)); + } + // Simulate a mouse click on the button. const eventOptions = { clientX: rect.left + rect.width / 2, From 7359114bf68ba63419e720d228476d27e8c7ead8 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Mar 2022 17:25:05 +0100 Subject: [PATCH 192/220] MOBILE-3833 behat: Fix pressElement helper Behat runtime helpers cannot use async/await because asynchronous errors won't be returned to the php runtime --- tests/behat/app_behat_runtime.js | 90 +++++++++++++++++++------------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index baab56f95..f1bac741b 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -511,55 +511,73 @@ }; /** - * Press an element. + * Make sure that an element is visible and wait to trigger the callback. * - * @param {HTMLElement} element Element to press. + * @param {HTMLElement} element Element. + * @param {Function} callback Callback called when the element is visible, passing bounding box parameter. */ - const pressElement = async function(element) { - // Scroll the item into view. + const ensureElementVisible = function(element, callback) { const initialRect = element.getBoundingClientRect(); element.scrollIntoView(false); - await new Promise(resolve => requestAnimationFrame(resolve)); + requestAnimationFrame(function () { + const rect = element.getBoundingClientRect(); - const rect = element.getBoundingClientRect(); + if (initialRect.y !== rect.y) { + setTimeout(function () { + callback(rect); + }, 300); + addPendingDelay(); - if (initialRect.y !== rect.y) { - await new Promise(resolve => setTimeout(resolve, 300)); - } + return; + } - // Simulate a mouse click on the button. - const eventOptions = { - clientX: rect.left + rect.width / 2, - clientY: rect.top + rect.height / 2, - bubbles: true, - view: window, - cancelable: true, - }; + callback(rect); + }); - // Events don't bubble up across Shadow DOM boundaries, and some buttons - // may not work without doing this. - const parentElement = getParentElement(element); - - if (parentElement && parentElement.matches('ion-button, ion-back-button')) { - element = parentElement; - } - - // There are some buttons in the app that don't respond to click events, for example - // buttons using the core-supress-events directive. That's why we need to send both - // click and mouse events. - element.dispatchEvent(new MouseEvent('mousedown', eventOptions)); - - setTimeout(() => { - element.dispatchEvent(new MouseEvent('mouseup', eventOptions)); - element.click(); - }, 300); - - // Mark busy until the button click finishes processing. addPendingDelay(); }; + /** + * Press an element. + * + * @param {HTMLElement} element Element to press. + */ + const pressElement = function(element) { + ensureElementVisible(element, function(rect) { + // Simulate a mouse click on the button. + const eventOptions = { + clientX: rect.left + rect.width / 2, + clientY: rect.top + rect.height / 2, + bubbles: true, + view: window, + cancelable: true, + }; + + // Events don't bubble up across Shadow DOM boundaries, and some buttons + // may not work without doing this. + const parentElement = getParentElement(element); + + if (parentElement && parentElement.matches('ion-button, ion-back-button')) { + element = parentElement; + } + + // There are some buttons in the app that don't respond to click events, for example + // buttons using the core-supress-events directive. That's why we need to send both + // click and mouse events. + element.dispatchEvent(new MouseEvent('mousedown', eventOptions)); + + setTimeout(() => { + element.dispatchEvent(new MouseEvent('mouseup', eventOptions)); + element.click(); + }, 300); + + // Mark busy until the button click finishes processing. + addPendingDelay(); + }); + }; + /** * Function to find and click an app standard button. * From 07af277a860d53f51fc99e8807e6bb59c5149374 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Mar 2022 17:25:24 +0100 Subject: [PATCH 193/220] MOBILE-3833 behat: Fix forum tests --- mod/forum/tests/behat/app_basic_usage.feature | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/mod/forum/tests/behat/app_basic_usage.feature index 6d59c7db0..015ac7f08 100755 --- a/mod/forum/tests/behat/app_basic_usage.feature +++ b/mod/forum/tests/behat/app_basic_usage.feature @@ -134,7 +134,7 @@ Feature: Test basic usage of forum activity in app When I press "Reply" in the app And I set the field "Message" to "not sent reply" in the app And I press "Post to forum" in the app - And I press "Display options" near "not sent reply" in the app + And I press "Display options" within "not sent reply" "ion-card" in the app Then I should find "Edit" in the app When I press "Edit" in the app @@ -244,6 +244,8 @@ Feature: Test basic usage of forum activity in app When I press "Reply" in the app And I set the field "Message" to "test2" in the app And I press "Post to forum" in the app + Then I should find "test2" "ion-card" in the app + When I enter the course "Course 1" as "teacher1" in the app And I press "Test forum name" in the app And I press "Auto-test" in the app From 98d68ad6f23bbd9ded6bde1429eabdc5526b6404 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Mar 2022 17:25:43 +0100 Subject: [PATCH 194/220] MOBILE-3833 behat: Fix external link tests --- tests/behat/navigation_externallinks.feature | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/behat/navigation_externallinks.feature b/tests/behat/navigation_externallinks.feature index 4abf963fe..e79737ac5 100644 --- a/tests/behat/navigation_externallinks.feature +++ b/tests/behat/navigation_externallinks.feature @@ -16,17 +16,17 @@ Feature: It opens external links properly. | forum | Test forum | Test forum | C1 | forum | And the following forum discussions exist in course "Course 1": | forum | user | name | message | - | Test forum | student1 | Forum topic | See moodle.org | + | Test forum | student1 | Forum topic | See moodle.org external link | Scenario: Click an external link When I enter the course "Course 1" as "student1" in the app And I press "Test forum" in the app And I press "Forum topic" in the app - And I press "moodle.org" in the app + And I press "moodle.org external link" in the app Then I should find "You are about to leave the app" in the app When I press "Cancel" in the app - And I press "moodle.org" in the app + And I press "moodle.org external link" in the app And I press "OK" in the app Then the app should have opened a browser tab with url "moodle.org" @@ -39,9 +39,9 @@ Feature: It opens external links properly. When I close the browser tab opened by the app When I close the popup in the app And I press "Forum topic" in the app - And I press "moodle.org" in the app + And I press "moodle.org external link" in the app And I select "Don't show again." in the app And I press "OK" in the app And I close the browser tab opened by the app - And I press "moodle.org" in the app + And I press "moodle.org external link" in the app Then the app should have opened a browser tab with url "moodle.org" From 12da416a51900ccaff4bcf4def3c03375696ed16 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 14 Mar 2022 14:48:37 +0100 Subject: [PATCH 195/220] MOBILE-3833 behat: Update course summary pages --- mod/course/tests/behat/app_basic_usage.feature | 2 +- mod/courses/tests/behat/app_basic_usage.feature | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mod/course/tests/behat/app_basic_usage.feature b/mod/course/tests/behat/app_basic_usage.feature index 2caa3442f..f1516594d 100755 --- a/mod/course/tests/behat/app_basic_usage.feature +++ b/mod/course/tests/behat/app_basic_usage.feature @@ -453,7 +453,7 @@ Feature: Test basic usage of one course in app Then I should find "Course summary" in the app And I should find "Course" in the app - When I press "Course" "ion-button" in the app + When I press "View course" "ion-button" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/mod/courses/tests/behat/app_basic_usage.feature index 5cb9f3953..fc59c4fbb 100755 --- a/mod/courses/tests/behat/app_basic_usage.feature +++ b/mod/courses/tests/behat/app_basic_usage.feature @@ -88,7 +88,7 @@ Feature: Test basic usage of courses in app When I press "Course 4" in the app Then I should find "Course 4" in the app - And the header should be "Course summary" in the app + And I should find "Course summary" in the app When I press the back button in the app And I set the field "Search" to "Course" in the app From 9997217214317c6e1b784a0f542d16a32d5f3843 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Mon, 14 Mar 2022 14:49:50 +0100 Subject: [PATCH 196/220] MOBILE-3833 behat: Delay verifying item selection Before this fix it was happening too fast some times and giving false negatives --- tests/behat/behat_app.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 603e298d2..a2737f79a 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -811,6 +811,8 @@ class behat_app extends behat_base { } // Check that it worked as expected. + usleep(1000000); + $result = $this->evaluate_script("return window.behat.isSelected($locatorjson);"); switch ($result) { From 82fa21f76bb223631b1f0674f5fdaf6f9e70312b Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 10 Mar 2022 12:07:15 +0100 Subject: [PATCH 197/220] MOBILE-3153 behat: Test User Tours --- tests/behat/app_behat_runtime.js | 5 +++- tests/behat/behat_app.php | 21 ++++++++++++++ tests/behat/usertours.feature | 49 ++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 tests/behat/usertours.feature diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 7d04487c1..b7b5ff709 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -415,9 +415,12 @@ case 'popover': containers = document.querySelectorAll('ion-app ion-popover.hydrated'); break; + case 'user-tour': + containers = document.querySelectorAll('core-user-tours-user-tour.is-active'); + break; default: // Other containerName or not implemented. - const containerSelector = 'ion-alert, ion-popover, ion-action-sheet, ion-modal, page-core-mainmenu, ion-app'; + const containerSelector = 'ion-alert, ion-popover, ion-action-sheet, ion-modal, core-user-tours-user-tour.is-active, page-core-mainmenu, ion-app'; containers = document.querySelectorAll(containerSelector); } diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index d056fc1be..d46116b56 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -69,6 +69,9 @@ class behat_app extends behat_base { /** @var bool Whether the app is running or not */ protected $apprunning = false; + /** @var array Config overrides */ + protected $appconfig = ['disableUserTours' => true]; + /** * Register listener. * @@ -540,6 +543,11 @@ class behat_app extends behat_base { }, false, 60); } + // Prepare testing config. + $configoverrides = json_encode($this->appconfig); + + $this->evaluate_script("configProvider.patchEnvironment($configoverrides)"); + // Continue only after JS finishes. $this->wait_for_pending_js(); } @@ -691,6 +699,7 @@ class behat_app extends behat_base { * Opens a custom link. * * @Given /^I open a custom link in the app for:$/ + * @param TableNode $data */ public function i_open_a_custom_link(TableNode $data) { global $DB, $CFG; @@ -742,6 +751,18 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } + /** + * Override app config. + * + * @Given /^the app has the following config:$/ + * @param TableNode $data + */ + public function the_app_has_the_following_config(TableNode $data) { + foreach ($data->getRows() as $configrow) { + $this->appconfig[$configrow[0]] = json_decode($configrow[1]); + } + } + /** * Clicks on / touches something that is visible in the app. * diff --git a/tests/behat/usertours.feature b/tests/behat/usertours.feature new file mode 100644 index 000000000..b9c4e0b64 --- /dev/null +++ b/tests/behat/usertours.feature @@ -0,0 +1,49 @@ +@app @javascript +Feature: User Tours work properly. + + Background: + Given the following "users" exist: + | username | firstname | lastname | + | student1 | Student | First | + | student2 | Student | Second | + And the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | student2 | C1 | student | + And the app has the following config: + | disableUserTours | false | + + Scenario: Acknowledge User Tours + When I enter the app + And I log in as "student1" + Then I should find "Explore your personal area" in the app + But I should not find "Expand to explore" in the app + + When I press "Got it" in the app + Then I should find "Expand to explore" in the app + But I should not find "Explore your personal area" in the app + + When I press "Got it" in the app + Then I should not find "Expand to explore" in the app + And I should not find "Explore your personal area" in the app + + When I press "My courses" in the app + And I press "Course 1" in the app + Then I should find "Find your way around" in the app + + When I press "Got it" in the app + Then I should not find "Find your way around" in the app + + When I press "Participants" in the app + And I press "Student First" in the app + Then I should find "Swipe left and right to navigate around" in the app + + When I press "Got it" in the app + Then I should not find "Swipe left and right to navigate around" in the app + + When I press the back button in the app + And I press "Student First" in the app + Then I should not find "Swipe left and right to navigate around" in the app From b5d2c11c15d4a401923b470534979025e1a5e35e Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 15 Mar 2022 10:39:33 +0100 Subject: [PATCH 198/220] MOBILE-3833 behat: Fix config overrides on reload --- tests/behat/behat_app.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 7f304be58..2419ae4b9 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -555,6 +555,7 @@ class behat_app extends behat_base { // Prepare testing config. $configoverrides = json_encode($this->appconfig); + $this->evaluate_script("document.cookie='MoodleAppConfig=$configoverrides'"); $this->evaluate_script("configProvider.patchEnvironment($configoverrides)"); // Continue only after JS finishes. From 6d5858a232f2c1b59085b845ebb0b956fe6dd1d6 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 17 Mar 2022 10:49:24 +0100 Subject: [PATCH 199/220] MOBILE-3833 usertours: Fix tests for old versions --- tests/behat/usertours.feature | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/behat/usertours.feature b/tests/behat/usertours.feature index b9c4e0b64..778c79845 100644 --- a/tests/behat/usertours.feature +++ b/tests/behat/usertours.feature @@ -30,8 +30,7 @@ Feature: User Tours work properly. Then I should not find "Expand to explore" in the app And I should not find "Explore your personal area" in the app - When I press "My courses" in the app - And I press "Course 1" in the app + When I enter the course "Course 1" in the app Then I should find "Find your way around" in the app When I press "Got it" in the app From 87f972ccefdebf27eb5cca4cdb1e409d40511e0a Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Wed, 30 Mar 2022 17:34:53 +0200 Subject: [PATCH 200/220] MOBILE-3833: Wait for scrolling to finish --- tests/behat/behat_app.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 2419ae4b9..5cc4eb45c 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -209,6 +209,9 @@ class behat_app extends behat_base { }); $this->wait_for_pending_js(); + + // Wait scroll animation to finish. + $this->getSession()->wait(300); } /** From eb0303d3013d366dd7050b0a2192e985de57cfc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 5 May 2022 12:19:58 +0200 Subject: [PATCH 201/220] MOBILE-4061 behat: Merge import behat files from local-moodlemobileapp --- .../templates/behat-plugin/classes}/output/mobile.php | 0 {db => scripts/templates/behat-plugin/db}/mobile.php | 0 {js => scripts/templates/behat-plugin/js}/mobile/index.js | 0 .../addons/messages/tests/behat/basic_usage.feature | 0 {mod => src/addons}/messages/tests/behat/navigation.feature | 0 {mod => src/addons}/messages/tests/behat/settings.feature | 0 .../addons/mod/assign/tests/behat/basic_usage.feature | 0 .../addons/mod/assign/tests/behat/navigation.feature | 0 .../addons/mod/chat/tests/behat/basic_usage.feature | 0 .../addons/mod/chat/tests/behat/navigation.feature | 0 .../addons/mod/choice/tests/behat/basic_usage.feature | 0 .../addons/mod/data/tests/behat/data_entries.feature | 0 .../addons/mod/data/tests/behat/data_sync.feature | 0 .../addons/mod/forum/tests/behat/basic_usage.feature | 0 .../addons/mod/forum/tests/behat/navigation.feature | 0 .../addons/mod/glossary/tests/behat/basic_usage.feature | 0 .../addons/mod/glossary/tests/behat/navigation.feature | 0 .../addons/mod/quiz/tests/behat/basic_usage.feature | 0 .../addons/mod/quiz/tests/behat/quiz_navigation.feature | 0 .../addons/mod/survey/tests/behat/basic_usage.feature | 0 .../core/features/comments/tests/behat/basic_usage.feature | 0 .../core/features/course/tests/behat/basic_usage.feature | 0 .../core/features/course/tests/behat/course_completion.feature | 0 .../core/features/course/tests/behat/courselist.feature | 0 .../core/features/courses/tests/behat/basic_usage.feature | 0 .../core/features/login/tests/behat/basic_usage.feature | 0 .../core/features/mainmenu/tests}/behat/mainmenu.feature | 0 .../features/settings/tests}/behat/settings_navigation.feature | 0 .../core/features/siteplugins/tests}/behat/plugins.feature | 0 .../core/features/usertours/tests}/behat/usertours.feature | 0 {tests => src/tests}/behat/navigation_activities.feature | 0 {tests => src/tests}/behat/navigation_deeplinks.feature | 0 {tests => src/tests}/behat/navigation_externallinks.feature | 0 {tests => src/tests}/behat/navigation_gestures.feature | 0 {tests => src/tests}/behat/navigation_splitview.feature | 0 35 files changed, 0 insertions(+), 0 deletions(-) rename {classes => scripts/templates/behat-plugin/classes}/output/mobile.php (100%) rename {db => scripts/templates/behat-plugin/db}/mobile.php (100%) rename {js => scripts/templates/behat-plugin/js}/mobile/index.js (100%) rename mod/messages/tests/behat/app_basic_usage.feature => src/addons/messages/tests/behat/basic_usage.feature (100%) rename {mod => src/addons}/messages/tests/behat/navigation.feature (100%) rename {mod => src/addons}/messages/tests/behat/settings.feature (100%) rename mod/assignment/tests/behat/app_basic_usage.feature => src/addons/mod/assign/tests/behat/basic_usage.feature (100%) rename mod/assignment/tests/behat/app_navigation.feature => src/addons/mod/assign/tests/behat/navigation.feature (100%) rename mod/chat/tests/behat/app_basic_usage.feature => src/addons/mod/chat/tests/behat/basic_usage.feature (100%) rename mod/chat/tests/behat/app_navigation.feature => src/addons/mod/chat/tests/behat/navigation.feature (100%) rename mod/choice/tests/behat/app_basic_usage.feature => src/addons/mod/choice/tests/behat/basic_usage.feature (100%) rename mod/data/tests/behat/app_data_entries.feature => src/addons/mod/data/tests/behat/data_entries.feature (100%) rename mod/data/tests/behat/app_data_sync.feature => src/addons/mod/data/tests/behat/data_sync.feature (100%) rename mod/forum/tests/behat/app_basic_usage.feature => src/addons/mod/forum/tests/behat/basic_usage.feature (100%) rename mod/forum/tests/behat/app_navigation.feature => src/addons/mod/forum/tests/behat/navigation.feature (100%) rename mod/glossary/tests/behat/app_basic_usage.feature => src/addons/mod/glossary/tests/behat/basic_usage.feature (100%) rename mod/glossary/tests/behat/app_navigation.feature => src/addons/mod/glossary/tests/behat/navigation.feature (100%) rename mod/quiz/tests/behat/app_basic_usage.feature => src/addons/mod/quiz/tests/behat/basic_usage.feature (100%) rename mod/quiz/tests/behat/app_quiz_navigation.feature => src/addons/mod/quiz/tests/behat/quiz_navigation.feature (100%) rename mod/survey/tests/behat/app_basic_usage.feature => src/addons/mod/survey/tests/behat/basic_usage.feature (100%) rename mod/comments/tests/behat/app_basic_usage.feature => src/core/features/comments/tests/behat/basic_usage.feature (100%) rename mod/course/tests/behat/app_basic_usage.feature => src/core/features/course/tests/behat/basic_usage.feature (100%) rename mod/course/tests/behat/app_course_completion.feature => src/core/features/course/tests/behat/course_completion.feature (100%) rename mod/course/tests/behat/app_courselist.feature => src/core/features/course/tests/behat/courselist.feature (100%) rename mod/courses/tests/behat/app_basic_usage.feature => src/core/features/courses/tests/behat/basic_usage.feature (100%) rename mod/login/tests/behat/app_basic_usage.feature => src/core/features/login/tests/behat/basic_usage.feature (100%) rename {tests => src/core/features/mainmenu/tests}/behat/mainmenu.feature (100%) rename {tests => src/core/features/settings/tests}/behat/settings_navigation.feature (100%) rename {tests => src/core/features/siteplugins/tests}/behat/plugins.feature (100%) rename {tests => src/core/features/usertours/tests}/behat/usertours.feature (100%) rename {tests => src/tests}/behat/navigation_activities.feature (100%) rename {tests => src/tests}/behat/navigation_deeplinks.feature (100%) rename {tests => src/tests}/behat/navigation_externallinks.feature (100%) rename {tests => src/tests}/behat/navigation_gestures.feature (100%) rename {tests => src/tests}/behat/navigation_splitview.feature (100%) diff --git a/classes/output/mobile.php b/scripts/templates/behat-plugin/classes/output/mobile.php similarity index 100% rename from classes/output/mobile.php rename to scripts/templates/behat-plugin/classes/output/mobile.php diff --git a/db/mobile.php b/scripts/templates/behat-plugin/db/mobile.php similarity index 100% rename from db/mobile.php rename to scripts/templates/behat-plugin/db/mobile.php diff --git a/js/mobile/index.js b/scripts/templates/behat-plugin/js/mobile/index.js similarity index 100% rename from js/mobile/index.js rename to scripts/templates/behat-plugin/js/mobile/index.js diff --git a/mod/messages/tests/behat/app_basic_usage.feature b/src/addons/messages/tests/behat/basic_usage.feature similarity index 100% rename from mod/messages/tests/behat/app_basic_usage.feature rename to src/addons/messages/tests/behat/basic_usage.feature diff --git a/mod/messages/tests/behat/navigation.feature b/src/addons/messages/tests/behat/navigation.feature similarity index 100% rename from mod/messages/tests/behat/navigation.feature rename to src/addons/messages/tests/behat/navigation.feature diff --git a/mod/messages/tests/behat/settings.feature b/src/addons/messages/tests/behat/settings.feature similarity index 100% rename from mod/messages/tests/behat/settings.feature rename to src/addons/messages/tests/behat/settings.feature diff --git a/mod/assignment/tests/behat/app_basic_usage.feature b/src/addons/mod/assign/tests/behat/basic_usage.feature similarity index 100% rename from mod/assignment/tests/behat/app_basic_usage.feature rename to src/addons/mod/assign/tests/behat/basic_usage.feature diff --git a/mod/assignment/tests/behat/app_navigation.feature b/src/addons/mod/assign/tests/behat/navigation.feature similarity index 100% rename from mod/assignment/tests/behat/app_navigation.feature rename to src/addons/mod/assign/tests/behat/navigation.feature diff --git a/mod/chat/tests/behat/app_basic_usage.feature b/src/addons/mod/chat/tests/behat/basic_usage.feature similarity index 100% rename from mod/chat/tests/behat/app_basic_usage.feature rename to src/addons/mod/chat/tests/behat/basic_usage.feature diff --git a/mod/chat/tests/behat/app_navigation.feature b/src/addons/mod/chat/tests/behat/navigation.feature similarity index 100% rename from mod/chat/tests/behat/app_navigation.feature rename to src/addons/mod/chat/tests/behat/navigation.feature diff --git a/mod/choice/tests/behat/app_basic_usage.feature b/src/addons/mod/choice/tests/behat/basic_usage.feature similarity index 100% rename from mod/choice/tests/behat/app_basic_usage.feature rename to src/addons/mod/choice/tests/behat/basic_usage.feature diff --git a/mod/data/tests/behat/app_data_entries.feature b/src/addons/mod/data/tests/behat/data_entries.feature similarity index 100% rename from mod/data/tests/behat/app_data_entries.feature rename to src/addons/mod/data/tests/behat/data_entries.feature diff --git a/mod/data/tests/behat/app_data_sync.feature b/src/addons/mod/data/tests/behat/data_sync.feature similarity index 100% rename from mod/data/tests/behat/app_data_sync.feature rename to src/addons/mod/data/tests/behat/data_sync.feature diff --git a/mod/forum/tests/behat/app_basic_usage.feature b/src/addons/mod/forum/tests/behat/basic_usage.feature similarity index 100% rename from mod/forum/tests/behat/app_basic_usage.feature rename to src/addons/mod/forum/tests/behat/basic_usage.feature diff --git a/mod/forum/tests/behat/app_navigation.feature b/src/addons/mod/forum/tests/behat/navigation.feature similarity index 100% rename from mod/forum/tests/behat/app_navigation.feature rename to src/addons/mod/forum/tests/behat/navigation.feature diff --git a/mod/glossary/tests/behat/app_basic_usage.feature b/src/addons/mod/glossary/tests/behat/basic_usage.feature similarity index 100% rename from mod/glossary/tests/behat/app_basic_usage.feature rename to src/addons/mod/glossary/tests/behat/basic_usage.feature diff --git a/mod/glossary/tests/behat/app_navigation.feature b/src/addons/mod/glossary/tests/behat/navigation.feature similarity index 100% rename from mod/glossary/tests/behat/app_navigation.feature rename to src/addons/mod/glossary/tests/behat/navigation.feature diff --git a/mod/quiz/tests/behat/app_basic_usage.feature b/src/addons/mod/quiz/tests/behat/basic_usage.feature similarity index 100% rename from mod/quiz/tests/behat/app_basic_usage.feature rename to src/addons/mod/quiz/tests/behat/basic_usage.feature diff --git a/mod/quiz/tests/behat/app_quiz_navigation.feature b/src/addons/mod/quiz/tests/behat/quiz_navigation.feature similarity index 100% rename from mod/quiz/tests/behat/app_quiz_navigation.feature rename to src/addons/mod/quiz/tests/behat/quiz_navigation.feature diff --git a/mod/survey/tests/behat/app_basic_usage.feature b/src/addons/mod/survey/tests/behat/basic_usage.feature similarity index 100% rename from mod/survey/tests/behat/app_basic_usage.feature rename to src/addons/mod/survey/tests/behat/basic_usage.feature diff --git a/mod/comments/tests/behat/app_basic_usage.feature b/src/core/features/comments/tests/behat/basic_usage.feature similarity index 100% rename from mod/comments/tests/behat/app_basic_usage.feature rename to src/core/features/comments/tests/behat/basic_usage.feature diff --git a/mod/course/tests/behat/app_basic_usage.feature b/src/core/features/course/tests/behat/basic_usage.feature similarity index 100% rename from mod/course/tests/behat/app_basic_usage.feature rename to src/core/features/course/tests/behat/basic_usage.feature diff --git a/mod/course/tests/behat/app_course_completion.feature b/src/core/features/course/tests/behat/course_completion.feature similarity index 100% rename from mod/course/tests/behat/app_course_completion.feature rename to src/core/features/course/tests/behat/course_completion.feature diff --git a/mod/course/tests/behat/app_courselist.feature b/src/core/features/course/tests/behat/courselist.feature similarity index 100% rename from mod/course/tests/behat/app_courselist.feature rename to src/core/features/course/tests/behat/courselist.feature diff --git a/mod/courses/tests/behat/app_basic_usage.feature b/src/core/features/courses/tests/behat/basic_usage.feature similarity index 100% rename from mod/courses/tests/behat/app_basic_usage.feature rename to src/core/features/courses/tests/behat/basic_usage.feature diff --git a/mod/login/tests/behat/app_basic_usage.feature b/src/core/features/login/tests/behat/basic_usage.feature similarity index 100% rename from mod/login/tests/behat/app_basic_usage.feature rename to src/core/features/login/tests/behat/basic_usage.feature diff --git a/tests/behat/mainmenu.feature b/src/core/features/mainmenu/tests/behat/mainmenu.feature similarity index 100% rename from tests/behat/mainmenu.feature rename to src/core/features/mainmenu/tests/behat/mainmenu.feature diff --git a/tests/behat/settings_navigation.feature b/src/core/features/settings/tests/behat/settings_navigation.feature similarity index 100% rename from tests/behat/settings_navigation.feature rename to src/core/features/settings/tests/behat/settings_navigation.feature diff --git a/tests/behat/plugins.feature b/src/core/features/siteplugins/tests/behat/plugins.feature similarity index 100% rename from tests/behat/plugins.feature rename to src/core/features/siteplugins/tests/behat/plugins.feature diff --git a/tests/behat/usertours.feature b/src/core/features/usertours/tests/behat/usertours.feature similarity index 100% rename from tests/behat/usertours.feature rename to src/core/features/usertours/tests/behat/usertours.feature diff --git a/tests/behat/navigation_activities.feature b/src/tests/behat/navigation_activities.feature similarity index 100% rename from tests/behat/navigation_activities.feature rename to src/tests/behat/navigation_activities.feature diff --git a/tests/behat/navigation_deeplinks.feature b/src/tests/behat/navigation_deeplinks.feature similarity index 100% rename from tests/behat/navigation_deeplinks.feature rename to src/tests/behat/navigation_deeplinks.feature diff --git a/tests/behat/navigation_externallinks.feature b/src/tests/behat/navigation_externallinks.feature similarity index 100% rename from tests/behat/navigation_externallinks.feature rename to src/tests/behat/navigation_externallinks.feature diff --git a/tests/behat/navigation_gestures.feature b/src/tests/behat/navigation_gestures.feature similarity index 100% rename from tests/behat/navigation_gestures.feature rename to src/tests/behat/navigation_gestures.feature diff --git a/tests/behat/navigation_splitview.feature b/src/tests/behat/navigation_splitview.feature similarity index 100% rename from tests/behat/navigation_splitview.feature rename to src/tests/behat/navigation_splitview.feature From dd9669a9559f986445e97ec5d26298bac9363402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 5 May 2022 12:38:06 +0200 Subject: [PATCH 202/220] MOBILE-4061 behat: Remove legacy Moodle App v3.9.4 tests --- .../mod/data/tests/behat/data_entries.feature | 183 -------- .../mod/data/tests/behat/data_sync.feature | 130 ------ .../glossary/tests/behat/basic_usage.feature | 320 -------------- .../survey/tests/behat/basic_usage.feature | 395 ------------------ .../comments/tests/behat/basic_usage.feature | 340 --------------- 5 files changed, 1368 deletions(-) delete mode 100644 src/addons/mod/data/tests/behat/data_entries.feature delete mode 100644 src/addons/mod/data/tests/behat/data_sync.feature delete mode 100755 src/addons/mod/glossary/tests/behat/basic_usage.feature delete mode 100755 src/addons/mod/survey/tests/behat/basic_usage.feature delete mode 100755 src/core/features/comments/tests/behat/basic_usage.feature diff --git a/src/addons/mod/data/tests/behat/data_entries.feature b/src/addons/mod/data/tests/behat/data_entries.feature deleted file mode 100644 index ca214a012..000000000 --- a/src/addons/mod/data/tests/behat/data_entries.feature +++ /dev/null @@ -1,183 +0,0 @@ -@mod @mod_data @app @app_upto3.9.4 @javascript -Feature: Users can manage entries in database activities - In order to populate databases - As a user - I need to add and manage entries to databases - - Background: - Given the following "users" exist: - | username | firstname | lastname | email | - | student1 | Student | 1 | student1@example.com | - | student2 | Student | 2 | student2@example.com | - | teacher1 | Teacher | 1 | teacher1@example.com | - And the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - | student2 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | data | Web links | Useful links | C1 | data1 | - And I log in as "teacher1" - And I am on "Course 1" course homepage - And I add a "Text input" field to "Web links" database and I fill the form with: - | Field name | URL | - | Field description | URL link | - And I add a "Text input" field to "Web links" database and I fill the form with: - | Field name | Description | - | Field description | Link description | - And I log out - - Scenario: Create entry - Given I enter the course "Course 1" as "student1" in the app - And I press "Web links" near "General" in the app - And I should see "No entries in database" - When I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - Then I should see "https://moodle.org/" - And I should see "Moodle community site" - - Scenario: Browse entry - Given I enter the course "Course 1" as "student1" in the app - And I press "Web links" near "General" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - When I enter the course "Course 1" as "student2" in the app - And I press "Web links" near "General" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - And I press "More" near "Moodle community site" in the app - Then I should see "Moodle community site" - And I should not see "Next" - And I should see "Previous" - And I press "Previous" in the app - And I should see "Moodle Cloud" - And I should see "Next" - And I should not see "Previous" - And I press "Next" in the app - And I should see "Moodle community site" - And I should not see "Moodle Cloud" - And I press "back" near "Web links" in the app - And I should see "Moodle community site" - And I should see "Moodle Cloud" - - Scenario: Students can not edit or delete other user's entries from list and single view in the app - Given I enter the course "Course 1" as "student1" in the app - And I press "Web links" near "General" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - When I enter the course "Course 1" as "student2" in the app - And I press "Web links" near "General" in the app - Then "Edit" "link" should not exist - And "Delete" "link" should not exist - And I press "More" in the app - And "Edit" "link" should not exist - And "Delete" "link" should not exist - - Scenario: Delete entry (student) & Update entry (student) - Given I enter the course "Course 1" as "student1" in the app - And I press "Web links" near "General" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - When I press "Edit" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - Then I should not see "https://moodle.org/" - And I should not see "Moodle community site" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Cancel" in the app - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Delete" in the app - And I should not see "Moodle Cloud" - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - And I press "More" in the app - And I press "Edit" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - And I should not see "https://moodle.org/" - And I should not see "Moodle community site" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Cancel" in the app - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Delete" in the app - And I should not see "Moodle Cloud" - And I should see "No entries in database" - - Scenario: Delete entry (teacher) & Update entry (teacher) - Given I enter the course "Course 1" as "student1" in the app - And I press "Web links" near "General" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - And I press "Add entries" in the app - And I set the field "URL" to "https://telegram.org/" in the app - And I set the field "Description" to "Telegram" in the app - And I press "Save" near "Web links" in the app - When I enter the course "Course 1" as "teacher1" in the app - And I press "Web links" near "General" in the app - Then I should see "https://moodle.org/" - And I should see "Moodle community site" - And I press "Edit" near "Moodle community site" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - And I should not see "https://moodle.org/" - And I should not see "Moodle community site" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I press "Delete" near "Moodle Cloud" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Cancel" in the app - And I should see "Moodle Cloud" - And I press "Delete" near "Moodle Cloud" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Delete" in the app - And I should not see "Moodle Cloud" - And I press "More" in the app - And I should see "https://telegram.org/" - And I should see "Telegram" - And I press "Edit" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - And I should not see "https://telegram.org/" - And I should not see "Telegram" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Cancel" in the app - And I should see "Moodle Cloud" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Delete" in the app - And I should not see "Moodle Cloud" diff --git a/src/addons/mod/data/tests/behat/data_sync.feature b/src/addons/mod/data/tests/behat/data_sync.feature deleted file mode 100644 index 04cc1c2c3..000000000 --- a/src/addons/mod/data/tests/behat/data_sync.feature +++ /dev/null @@ -1,130 +0,0 @@ -@mod @mod_data @app @app_upto3.9.4 @javascript -Feature: Users can store entries in database activities when offline and sync when online - In order to populate databases while offline - As a user - I need to add and manage entries to databases and sync then when online - - Background: - Given the following "users" exist: - | username | firstname | lastname | email | - | student1 | Student | 1 | student1@example.com | - | student2 | Student | 2 | student2@example.com | - | teacher1 | Teacher | 1 | teacher1@example.com | - And the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - | student2 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | - | data | Web links | Useful links | C1 | data1 | - And I log in as "teacher1" - And I am on "Course 1" course homepage - And I add a "Text input" field to "Web links" database and I fill the form with: - | Field name | URL | - | Field description | URL link | - And I add a "Text input" field to "Web links" database and I fill the form with: - | Field name | Description | - | Field description | Link description | - And I log out - - @app_from3.7 - Scenario: Create entry (offline) - Given I enter the course "Course 1" as "student1" in the app - And I press "Web links" near "General" in the app - And I switch offline mode to "true" - And I should see "No entries in database" - When I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - Then I should see "https://moodle.org/" - And I should see "Moodle community site" - And I should see "This Database has offline data to be synchronised" - And I press "back" near "Web links" in the app - And I switch offline mode to "false" - And I press "Web links" near "General" in the app - And I should see "https://moodle.org/" - And I should see "Moodle community site" - And I should not see "This Database has offline data to be synchronised" - - @app_from3.7 - Scenario: Update entry (offline) & Delete entry (offline) - Given I enter the course "Course 1" as "student1" in the app - And I press "Web links" near "General" in the app - And I should see "No entries in database" - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - And I should see "https://moodle.org/" - And I should see "Moodle community site" - And I press "Display options" in the app - And I press "Download" in the app - And I wait until the page is ready - And I switch offline mode to "true" - When I press "Edit" in the app - And I set the field "URL" to "https://moodlecloud.com/" in the app - And I set the field "Description" to "Moodle Cloud" in the app - And I press "Save" near "Web links" in the app - Then I should not see "https://moodle.org/" - And I should not see "Moodle community site" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I should see "This Database has offline data to be synchronised" - And I press "back" near "Web links" in the app - And I switch offline mode to "false" - And I press "Web links" near "General" in the app - And I should not see "https://moodle.org/" - And I should not see "Moodle community site" - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I should not see "This Database has offline data to be synchronised" - And I press "Display options" in the app - And I press "Refresh" in the app - And I wait until the page is ready - And I switch offline mode to "true" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Delete" in the app - And I should see "https://moodlecloud.com/" - And I should see "Moodle Cloud" - And I should see "This Database has offline data to be synchronised" - And I press "back" near "Web links" in the app - And I switch offline mode to "false" - And I press "Web links" near "General" in the app - And I should not see "https://moodlecloud.com/" - And I should not see "Moodle Cloud" - And I should not see "This Database has offline data to be synchronised" - - @app_from3.7 - Scenario: Students can undo deleting entries to a database in the app while offline - Given I enter the course "Course 1" as "student1" in the app - And I press "Web links" near "General" in the app - And I should see "No entries in database" - And I press "Add entries" in the app - And I set the field "URL" to "https://moodle.org/" in the app - And I set the field "Description" to "Moodle community site" in the app - And I press "Save" near "Web links" in the app - And I should see "https://moodle.org/" - And I should see "Moodle community site" - And I press "Display options" in the app - And I press "Download" in the app - And I wait until the page is ready - When I switch offline mode to "true" - And I press "Delete" in the app - And I should see "Are you sure you want to delete this entry?" - And I press "Delete" in the app - And I should see "https://moodle.org/" - And I should see "Moodle community site" - And I should see "This Database has offline data to be synchronised" - And I press "Restore" in the app - And I press "back" near "Web links" in the app - And I switch offline mode to "false" - And I press "Web links" near "General" in the app - Then I should see "https://moodle.org/" - And I should see "Moodle community site" - And I should not see "This Database has offline data to be synchronised" diff --git a/src/addons/mod/glossary/tests/behat/basic_usage.feature b/src/addons/mod/glossary/tests/behat/basic_usage.feature deleted file mode 100755 index 5fcb2e3dd..000000000 --- a/src/addons/mod/glossary/tests/behat/basic_usage.feature +++ /dev/null @@ -1,320 +0,0 @@ -@mod @mod_glossary @app @app_upto3.9.4 @javascript -Feature: Test basic usage of glossary in app - In order to participate in the glossaries while using the mobile app - As a student - I need basic glossary functionality to work - - Background: - Given the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | teacher | teacher1@example.com | - | teacher2 | Teacher2 | teacher2 | teacher2@example.com | - | student1 | Student | student | student1@example.com | - And the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | teacher2 | C1 | editingteacher | - | student1 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | mainglossary | allowcomments | assessed | scale | - | glossary | Test glossary | glossary description | C1 | gloss1 | 1 | 1 | 1 | 1 | - And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | - | forum | Test forum name | Test forum | C1 | forum | 0 | - - @app @3.8.0 - Scenario: View a glossary and its terms - When I enter the course "Course 1" as "student1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - - When I press "car" in the app - Then I should see "car" - And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." - - @app @3.8.0 - Scenario: Change filters (include search) - When I enter the course "Course 1" as "student1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - - When I press "Search" in the app - And I set the field "Search query" to "something" in the app - And I press "search" near "No entries were found." in the app - Then I should see "No entries were found." - - When I set the field "Search query" to "potato" in the app - And I press "search" near "No entries were found." in the app - And I set the field "Search query" to " " in the app - And I press "Display options" in the app - And I press "Refresh" in the app - And I press "potato" in the app - Then I should see "potato" - And I should see "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." - - @app @3.8.0 - Scenario: Navigate to glossary terms by link (auto-linking) - When the "glossary" filter is "on" - And I enter the course "Course 1" as "student1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "This entry should be automatically linked" in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "This entry should be automatically linked" in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "This entry should be automatically linked" in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - - When I press the back button in the app - And I press "Test forum name" in the app - And I press "add" in the app - And I set the field "Subject" to "Testing auto-link glossary" - And I set the field "Message" to "Glossary terms auto-linked: potato car mountain" in the app - And I press "Post to forum" in the app - And I press "Testing auto-link glossary" near "Last post a few seconds ago" in the app - Then I should see "car" - - When I press "car" in the app - Then the header should be "car" in the app - And I should see "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." - - When I press the back button in the app - And I press "mountain" in the app - Then the header should be "mountain" in the app - And I should see "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." - - @app @3.8.0 - Scenario: See comments - # Create entries as a student - When I enter the course "Course 1" as "student1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - - When I press "mountain" in the app - Then I should see "Comments (0)" - - # Write comments as a teacher - When I enter the course "Course 1" as "teacher1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - Then I should see "Comments (0)" - - When I press "Comments" in the app - And I should see "No comments" - - When I press "close" in the app - And I set the field "Add a comment..." to "teacher first comment" in the app - And I press "Save comment" in the app - Then I should see "teacher first comment" - - When I press "close" in the app - And I set the field "Add a comment..." to "teacher second comment" in the app - And I press "Save comment" in the app - Then I should see "teacher first comment" - And I should see "teacher second comment" - - # View comments as a student - When I enter the course "Course 1" as "student1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - Then I should see "Comments (2)" - - When I press "Comments" in the app - And I should see "teacher first comment" - And I should see "teacher second comment" - - @app @3.8.0 - Scenario: Prefetch - When I enter the course "Course 1" as "student1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - - When I press "Display options" in the app - And I press "Download" in the app - And I press the back button in the app - And I press the back button in the app - And I enter the course "Course 1" in the app - And I switch offline mode to "true" - And I press "Test glossary" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - - When I press "mountain" in the app - Then I should see "mountain" - And I should see "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." - And I should not see "Comments cannot be retrieved" - And I should see "Comments (0)" - - @app @3.8.0 - Scenario: Sync - When I enter the course "Course 1" as "student1" in the app - And I press "Test glossary" in the app - And I switch offline mode to "true" - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I should see "Entries to be synced" - And I should see "This Glossary has offline data to be synchronised." - - When I switch offline mode to "false" - And I press "close" in the app - And I set the field "Concept" to "testSync" in the app - And I set the field "Definition" to "testSync" in the app - And I press "Save" in the app - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - And I should see "testSync" - But I should not see "Entries to be synced" - And I should not see "This Glossary has offline data to be synchronised." - - @app @3.8.0 - Scenario: Add/view ratings - # Create entries as a student - When I enter the course "Course 1" as "student1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "car" in the app - And I set the field "Definition" to "A car (or automobile) is a wheeled motor vehicle used for transportation. Most definitions of cars say that they run primarily on roads, seat one to eight people, have four tires, and mainly transport people rather than goods." in the app - And I press "Save" in the app - And I press "close" in the app - And I set the field "Concept" to "mountain" in the app - And I set the field "Definition" to "A mountain is a large landform that rises above the surrounding land in a limited area, usually in the form of a peak." in the app - And I press "Save" in the app - Then the header should be "Test glossary" in the app - And I should see "car" - And I should see "mountain" - And I should see "potato" - - # Rate entries as teacher1 - When I enter the course "Course 1" as "teacher1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - Then I should see "Average of ratings: -" - - When I press "None" in the app - And I press "1" in the app - Then I should see "Average of ratings: 1" - - # Rate entries as teacher2 - When I enter the course "Course 1" as "teacher2" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - And I switch offline mode to "true" - And I press "None" in the app - And I press "0" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "Average of ratings: 1" - - When I switch offline mode to "false" - And I press the back button in the app - Then I should see "This Glossary has offline data to be synchronised." - - When I press "Display options" in the app - And I press "Synchronise now" in the app - And I press "mountain" in the app - Then I should see "Average of ratings: 0.5" - - # View ratings as a student - When I enter the course "Course 1" as "student1" in the app - And I press "Test glossary" in the app - And I press "mountain" in the app - Then the header should be "mountain" in the app - But I should not see "Average of ratings: 0.5" diff --git a/src/addons/mod/survey/tests/behat/basic_usage.feature b/src/addons/mod/survey/tests/behat/basic_usage.feature deleted file mode 100755 index 09a72b533..000000000 --- a/src/addons/mod/survey/tests/behat/basic_usage.feature +++ /dev/null @@ -1,395 +0,0 @@ -@mod @mod_survey @app @app_upto3.9.4 @javascript -Feature: Test basic usage of survey activity in app - In order to participate in surveys while using the mobile app - As a student - I need basic survey functionality to work - - Background: - Given the following "courses" exist: - | fullname | shortname | - | Course 1 | C1 | - And the following "users" exist: - | username | - | student1 | - | teacher1 | - And the following "course enrolments" exist: - | user | course | role | - | student1 | C1 | student | - | teacher1 | C1 | editingteacher | - And the following "activities" exist: - | activity | name | intro | course | idnumber | groupmode | - | survey | Test survey name | Test survey | C1 | survey | 0 | - - @app @3.8.0 - Scenario: Answer a survey & View results (ATTLS) - When I enter the course "Course 1" as "student1" in the app - And I press "Test survey name" in the app - And I press "Choose" near "1. In evaluating what someone says, I focus on the quality of their argument, not on the person who's presenting it." in the app - And I press "Strongly agree" in the app - And I press "Choose" near "2. I like playing devil's advocate - arguing the opposite of what someone is saying." in the app - And I press "Strongly disagree" in the app - And I press "Choose" near "3. I like to understand where other people are 'coming from', what experiences have led them to feel the way they do." in the app - And I press "Somewhat agree" in the app - And I press "Choose" near "4. The most important part of my education has been learning to understand people who are very different to me." in the app - And I press "Somewhat disagree" in the app - And I press "Choose" near "5. I feel that the best way for me to achieve my own identity is to interact with a variety of other people." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "6. I enjoy hearing the opinions of people who come from backgrounds different to mine - it helps me to understand how the same things can be seen in such different ways." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "7. I find that I can strengthen my own position through arguing with someone who disagrees with me." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "8. I am always interested in knowing why people say and believe the things they do." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "9. I often find myself arguing with the authors of books that I read, trying to logically figure out why they're wrong." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "10. It's important for me to remain as objective as possible when I analyze something." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "11. I try to think with people instead of against them." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "12. I have certain criteria I use in evaluating arguments." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "13. I'm more likely to try to understand someone else's opinion than to try to evaluate it." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "14. I try to point out weaknesses in other people's thinking to help them clarify their arguments." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "15. I tend to put myself in other people's shoes when discussing controversial issues, to see why they think the way they do." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "16. One could call my way of analysing things 'putting them on trial' because I am careful to consider all the evidence." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "17. I value the use of logic and reason over the incorporation of my own concerns when solving problems." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "18. I can obtain insight into opinions that differ from mine through empathy." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "19. When I encounter people whose opinions seem alien to me, I make a deliberate effort to 'extend' myself into that person, to try to see how they could have those opinions." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Choose" near "20. I spend time figuring out what's 'wrong' with things. For example, I'll look for something in a literary interpretation that isn't argued well enough." in the app - And I press "Somewhat agree" near "Neither agree nor disagree" in the app - And I press "Submit" in the app - And I press "OK" in the app - And I press "open" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" - - @app @3.8.0 - Scenario: Answer a survey & View results (Critical incidents) - Given the following "activities" exist: - | activity | name | intro | template |course | idnumber | groupmode | - | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | - When I enter the course "Course 1" as "student1" in the app - And I press "Test survey critical incidents" in the app - And I set the field with xpath "//textarea[@aria-label='At what moment in class were you most engaged as a learner?']" to "1st answer" - And I set the field with xpath "//textarea[@aria-label='At what moment in class were you most distanced as a learner?']" to "2nd answer" - And I set the field with xpath "//textarea[@aria-label='What action from anyone in the forums did you find most affirming or helpful?']" to "3rd answer" - And I set the field with xpath "//textarea[@aria-label='What action from anyone in the forums did you find most puzzling or confusing?']" to "4th answer" - And I set the field with xpath "//textarea[@aria-label='What event surprised you most?']" to "5th answer" - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "Results" - - When I press "Results" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "Test survey critical incidents" - And I should see "1st answer" - And I should see "2nd answer" - And I should see "3rd answer" - And I should see "4th answer" - And I should see "5th answer" - - @app @3.8.0 - Scenario: Answer a survey & View results (Colles actual) - Given the following "activities" exist: - | activity | name | intro | template |course | idnumber | groupmode | - | survey | Test survey Colles (actual) | Test survey1 | 1 | C1 | survey1 | 0 | - When I enter the course "Course 1" as "student1" in the app - And I press "Test survey Colles (actual)" in the app - And I press "Choose" near "1. my learning focuses on issues that interest me." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "2. what I learn is important for my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "3. I learn how to improve my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "4. what I learn connects well with my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "5. I think critically about how I learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "6. I think critically about my own ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "7. I think critically about other students' ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "8. I think critically about ideas in the readings." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "9. I explain my ideas to other students." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "10. I ask other students to explain their ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "11. other students ask me to explain my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "12. other students respond to my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "13. the tutor stimulates my thinking." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "14. the tutor encourages me to participate." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "15. the tutor models good discourse." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "16. the tutor models critical self-reflection." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "17. other students encourage my participation." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "18. other students praise my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "19. other students value my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "20. other students empathise with my struggle to learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "21. I make good sense of other students' messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "22. other students make good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "23. I make good sense of the tutor's messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "24. the tutor makes good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "25. How long did this survey take you to complete?" in the app - And I press "under 1 min" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "You have completed this survey" - - When I press "Results" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" - - @app @3.8.0 - Scenario: Answer a survey & View results (Colles preferred) - Given the following "activities" exist: - | activity | name | intro | template | course | idnumber | groupmode | - | survey | Test survey Colles (preferred) | Test survey1 | 2 | C1 | survey1 | 0 | - When I enter the course "Course 1" as "student1" in the app - And I press "Test survey Colles (preferred)" in the app - And I press "Choose" near "1. my learning focuses on issues that interest me." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "2. what I learn is important for my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "3. I learn how to improve my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "4. what I learn connects well with my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "5. I think critically about how I learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "6. I think critically about my own ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "7. I think critically about other students' ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "8. I think critically about ideas in the readings." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "9. I explain my ideas to other students." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "10. I ask other students to explain their ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "11. other students ask me to explain my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "12. other students respond to my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "13. the tutor stimulates my thinking." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "14. the tutor encourages me to participate." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "15. the tutor models good discourse." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "16. the tutor models critical self-reflection." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "17. other students encourage my participation." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "18. other students praise my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "19. other students value my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "20. other students empathise with my struggle to learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "21. I make good sense of other students' messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "22. other students make good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "23. I make good sense of the tutor's messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "24. the tutor makes good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "25. How long did this survey take you to complete?" in the app - And I press "under 1 min" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "You have completed this survey" - - When I press "Results" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" - - @app @3.8.0 - Scenario: Answer a survey & View results (Colles preferred amd actual) - Given the following "activities" exist: - | activity | name | intro | template | course | idnumber | groupmode | - | survey | Test survey Colles (preferred and actual) | Test survey1 | 3 | C1 | survey1 | 0 | - When I enter the course "Course 1" as "student1" in the app - And I press "Test survey Colles (preferred and actual)" in the app - And I press "Choose" near "1. I prefer that my learning focuses on issues that interest me." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "2. I found that my learning focuses on issues that interest me." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "3. I prefer that what I learn is important for my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "4. I found that what I learn is important for my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "5. I prefer that I learn how to improve my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "6. I found that I learn how to improve my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "7. I prefer that what I learn connects well with my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "8. I found that what I learn connects well with my professional practice." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "9. I prefer that I think critically about how I learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "10. I found that I think critically about how I learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "11. I prefer that I think critically about my own ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "12. I found that I think critically about my own ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "13. I prefer that I think critically about other students' ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "14. I found that I think critically about other students' ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "15. I prefer that I think critically about ideas in the readings." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "16. I found that I think critically about ideas in the readings." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "17. I prefer that I explain my ideas to other students." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "18. I found that I explain my ideas to other students." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "19. I prefer that I ask other students to explain their ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "20. I found that I ask other students to explain their ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "21. I prefer that other students ask me to explain my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "22. I found that other students ask me to explain my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "23. I prefer that other students respond to my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "24. I found that other students respond to my ideas." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "25. I prefer that the tutor stimulates my thinking." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "26. I found that the tutor stimulates my thinking." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "27. I prefer that the tutor encourages me to participate." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "28. I found that the tutor encourages me to participate." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "29. I prefer that the tutor models good discourse." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "30. I found that the tutor models good discourse." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "31. I prefer that the tutor models critical self-reflection." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "32. I found that the tutor models critical self-reflection." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "33. I prefer that other students encourage my participation." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "34. I found that other students encourage my participation." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "35. I prefer that other students praise my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "36. I found that other students praise my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "37. I prefer that other students value my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "38. I found that other students value my contribution." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "39. I prefer that other students empathise with my struggle to learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "40. I found that other students empathise with my struggle to learn." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "41. I prefer that I make good sense of other students' messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "42. I found that I make good sense of other students' messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "43. I prefer that other students make good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "44. I found that other students make good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "45. I prefer that I make good sense of the tutor's messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "46. I found that I make good sense of the tutor's messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "47. I prefer that the tutor makes good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "48. I found that the tutor makes good sense of my messages." in the app - And I press "Sometimes" near "Often" in the app - And I press "Choose" near "49. How long did this survey take you to complete?" in the app - And I press "1-2 min" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "You have completed this survey" - - When I press "Results" in the app - And I switch to the browser tab opened by the app - And I log in as "student1" - Then I should see "You've completed this survey. The graph below shows a summary of your results compared to the class averages." - And I should see "1 people have completed this survey so far" - - @app @3.8.0 - Scenario: Answer survey offline & Sync survey - Given the following "activities" exist: - | activity | name | intro | template | course | idnumber | groupmode | - | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | - When I enter the course "Course 1" as "student1" in the app - And I press "Test survey critical incidents" in the app - And I switch offline mode to "true" - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "This Survey has offline data to be synchronised." - - When I switch offline mode to "false" - And I press the back button in the app - And I press "Test survey critical incidents" in the app - And I press "Display options" in the app - And I press "Refresh" in the app - Then I should see "Results" - And I should see "You have completed this survey." - But I should not see "This Survey has offline data to be synchronised." - - @app @3.8.0 - Scenario: Prefetch & Auto-sync survey - Given the following "activities" exist: - | activity | name | intro | template | course | idnumber | groupmode | - | survey | Test survey critical incidents | Test survey1 | 5 | C1 | survey1 | 0 | - When I enter the course "Course 1" as "student1" in the app - And I press "Display options" in the app - And I press "Course downloads" in the app - And I press "cloud download" near "Test survey critical incidents" in the app - And I press the back button in the app - And I switch offline mode to "true" - And I press "Test survey name" in the app - Then I should see "There was a problem connecting to the site. Please check your connection and try again." - - When I press "OK" in the app - And I press the back button in the app - And I press "Test survey critical incidents" in the app - And I press "Submit" in the app - And I press "OK" in the app - Then I should see "This Survey has offline data to be synchronised." - - When I switch offline mode to "false" - And I run cron tasks in the app - Then I should not see "This Survey has offline data to be synchronised." - And I should see "You have completed this survey." diff --git a/src/core/features/comments/tests/behat/basic_usage.feature b/src/core/features/comments/tests/behat/basic_usage.feature deleted file mode 100755 index c398038d4..000000000 --- a/src/core/features/comments/tests/behat/basic_usage.feature +++ /dev/null @@ -1,340 +0,0 @@ -@mod @mod_comments @app @app_upto3.9.4 @javascript -Feature: Test basic usage of comments in app - In order to participate in the comments while using the mobile app - As a student - I need basic comments functionality to work - - Background: - Given the following "users" exist: - | username | firstname | lastname | email | - | teacher1 | Teacher | teacher | teacher1@example.com | - | student1 | Student | student | student1@example.com | - And the following "courses" exist: - | fullname | shortname | category | - | Course 1 | C1 | 0 | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - And the following "activities" exist: - | activity | name | intro | course | idnumber | mainglossary | allowcomments | assessed | scale | - | glossary | Test glossary | glossary description | C1 | gloss1 | 1 | 1 | 1 | 1 | - And the following "activities" exist: - | activity | name | intro | course | idnumber | comments | - | data | Data | Data info | C1 | data1 | 1 | - - @app @3.8.0 - Scenario: Add comments & Delete comments (database) - # Create database entry and comment as a teacher - Given I enter the course "Course 1" as "teacher1" in the app - And I press "Data" in the app - And I press "Display options" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "teacher1" - And I add a "Text input" field to "Data" database and I fill the form with: - | Field name | Test field name | - | Field description | Test field description | - And I press "Save" - And I close the browser tab opened by the app - When I enter the course "Course 1" as "teacher1" in the app - And I press "Data" in the app - And I press "add" in the app - And I set the field "Test field name" to "Test" in the app - And I press "Save" in the app - And I press "More" in the app - And I press "Comments (0)" in the app - And I press "close" in the app - And I set the field "Add a comment..." to "comment test teacher" in the app - And I press "Save comment" in the app - Then I should see "Comment created" - And I should see "comment test teacher" - - When I press the back button in the app - And I should see "Comments (1)" - - # Create and delete comments as a student - When I enter the course "Course 1" as "student1" in the app - And I press "Data" in the app - And I press "More" in the app - And I press "Comments (1)" in the app - And I press "close" in the app - And I set the field "Add a comment..." to "comment test student" in the app - And I press "Save comment" in the app - Then I should see "Comment created" - And I should see "comment test teacher" - And I should see "comment test student" - - When I press the back button in the app - And I press "Comments (2)" in the app - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should see "comment test teacher" - But I should not see "comment test student" - - When I press the back button in the app - Then I should see "Comments (1)" - - @app @3.8.0 - Scenario: Add comments offline & Delete comments offline & Sync comments (database) - Given I enter the course "Course 1" as "teacher1" in the app - And I press "Data" in the app - And I press "Display options" in the app - And I press "Open in browser" in the app - And I switch to the browser tab opened by the app - And I log in as "teacher1" - And I add a "Text input" field to "Data" database and I fill the form with: - | Field name | Test field name | - | Field description | Test field description | - And I press "Save" - And I close the browser tab opened by the app - When I enter the course "Course 1" as "teacher1" in the app - And I press "Data" in the app - And I press "add" in the app - And I set the field "Test field name" to "Test" in the app - And I press "Save" in the app - And I press "More" in the app - And I press "Comments (0)" in the app - And I switch offline mode to "true" - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "There are offline comments to be synchronised." - And I should see "comment test" - - When I press the back button in the app - And I press "Comments (0)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should see "comment test" - But I should not see "There are offline comments to be synchronised." - - When I press the back button in the app - And I press "Comments (1)" in the app - And I switch offline mode to "true" - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should see "There are offline comments to be synchronised." - And I should see "Deleted offline" - And I should see "comment test" - - When I press the back button in the app - And I press "Comments (1)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should not see "There are offline comments to be synchronised." - And I should not see "comment test" - - When I press the back button in the app - And I should see "Comments (0)" - - @app @3.8.0 - Scenario: Add comments & delete comments (glossary) - # Create glossary entry and comment as a teacher - When I enter the course "Course 1" as "teacher1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "potato" in the app - And I press "Comments (0)" in the app - And I press "close" in the app - And I set the field "Add a comment..." to "comment test teacher" in the app - And I press "Save comment" in the app - Then I should see "Comment created" - And I should see "comment test teacher" - And I press the back button in the app - And I should see "Comments (1)" - - # Create and delete comments as a student - When I enter the course "Course 1" as "student1" in the app - And I press "Test glossary" in the app - And I press "potato" in the app - And I press "Comments (1)" in the app - And I press "close" in the app - And I set the field "Add a comment..." to "comment test student" in the app - And I press "Save comment" in the app - Then I should see "Comment created" - And I should see "comment test teacher" - And I should see "comment test student" - - When I press the back button in the app - And I press "Comments (2)" in the app - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should see "comment test teacher" - But I should not see "comment test student" - - When I press the back button in the app - And I should see "Comments (1)" - - @app @3.8.0 - Scenario: Add comments offline & Delete comments offline & Sync comments (glossary) - When I enter the course "Course 1" as "teacher1" in the app - And I press "Test glossary" in the app - And I press "close" in the app - And I set the field "Concept" to "potato" in the app - And I set the field "Definition" to "The potato is a root vegetable native to the Americas, a starchy tuber of the plant Solanum tuberosum, and the plant itself, a perennial in the family Solanaceae." in the app - And I press "Save" in the app - And I press "potato" in the app - And I press "Comments (0)" in the app - And I switch offline mode to "true" - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "There are offline comments to be synchronised." - And I should see "comment test" - - When I press the back button in the app - And I press "Comments (0)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should see "comment test" - But I should not see "There are offline comments to be synchronised." - - When I press the back button in the app - And I press "Comments (1)" in the app - And I switch offline mode to "true" - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should see "There are offline comments to be synchronised." - And I should see "Deleted offline" - And I should see "comment test" - - When I press the back button in the app - And I press "Comments (1)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should not see "There are offline comments to be synchronised." - And I should not see "comment test" - - When I press the back button in the app - And I should see "Comments (0)" - - @app @3.8.0 - Scenario: Add comments & Delete comments (blogs) - # Create blog as a teacher - Given I enter the course "Course 1" as "teacher1" in the app - And I press "menu" in the app - And I press "Website" in the app - And I switch to the browser tab opened by the app - And I follow "Log in" - And I log in as "teacher1" - And I click on "Side panel" "button" - And I follow "C1" - And I press "Turn editing on" - And I click on "Side panel" "button" - And I follow "Add a block" - And I follow "Blog menu" - And I follow "Add an entry about this course" - And I set the field "Entry title" to "Blog test" - And I set the field "Blog entry body" to "Blog body" - And I press "Save changes" - And I close the browser tab opened by the app - - # Create and delete comments as a student - When I enter the course "Course 1" as "student1" in the app - And I press "menu" in the app - And I press "Site blog" in the app - Then I should see "Blog test" - And I should see "Blog body" - - When I press "Comments (0)" in the app - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Comment created" - And I should see "comment test" - - When I press the back button in the app - And I press "Comments (1)" in the app - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - But I should not see "comment test" - - When I press the back button in the app - Then I should see "Comments (0)" - - @app @3.8.0 - Scenario: Add comments offline & Delete comments offline & Sync comments (blogs) - # Create blog as a teacher - Given I enter the course "Course 1" as "teacher1" in the app - And I press "menu" in the app - And I press "Website" in the app - And I switch to the browser tab opened by the app - And I follow "Log in" - And I log in as "teacher1" - And I click on "Side panel" "button" - And I follow "C1" - And I press "Turn editing on" - And I click on "Side panel" "button" - And I follow "Add a block" - And I follow "Blog menu" - And I follow "Add an entry about this course" - And I set the field "Entry title" to "Blog test" - And I set the field "Blog entry body" to "Blog body" - And I press "Save changes" - And I close the browser tab opened by the app - - # Create and delete comments as a student - When I enter the course "Course 1" as "student1" in the app - And I press "menu" in the app - And I press "Site blog" in the app - Then I should see "Blog test" - And I should see "Blog body" - - When I press "Comments (0)" in the app - And I switch offline mode to "true" - And I press "close" in the app - And I set the field "Add a comment..." to "comment test" in the app - And I press "Save comment" in the app - Then I should see "Data stored in the device because it couldn't be sent. It will be sent automatically later." - And I should see "There are offline comments to be synchronised." - And I should see "comment test" - - When I press the back button in the app - And I press "Comments (0)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should see "comment test" - But I should not see "There are offline comments to be synchronised." - - When I press the back button in the app - And I press "Comments (1)" in the app - And I switch offline mode to "true" - And I press "Delete" in the app - And I press "trash" in the app - And I press "Delete" near "Cancel" in the app - Then I should see "Comment deleted" - And I should see "There are offline comments to be synchronised." - And I should see "Deleted offline" - And I should see "comment test" - - When I press the back button in the app - And I press "Comments (1)" in the app - And I switch offline mode to "false" - And I press "Display options" in the app - And I press "Synchronise now" in the app - Then I should not see "There are offline comments to be synchronised." - And I should not see "comment test" - - When I press the back button in the app - Then I should see "Comments (0)" From 5b5d654b32335b1ac2fece7d1eec8a0aadb222c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 2 May 2022 16:39:40 +0200 Subject: [PATCH 203/220] MOBILE-4061 behat: Adapt files to new behat plugin --- scripts/build-behat-plugin.js | 3 ++- scripts/templates/behat-plugin/classes/output/mobile.php | 2 +- scripts/templates/behat-plugin/db/mobile.php | 4 ++-- tests/behat/app_behat_runtime.js | 2 +- tests/behat/behat_app.php | 6 +++--- tests/behat/classes/performance_measure.php | 4 +++- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/scripts/build-behat-plugin.js b/scripts/build-behat-plugin.js index 9d12c355d..810243ac6 100755 --- a/scripts/build-behat-plugin.js +++ b/scripts/build-behat-plugin.js @@ -80,7 +80,8 @@ async function main() { } const newPath = featurePath.substring(0, featurePath.length - ('/tests/behat'.length)); - const prefix = relative(behatTempFeaturesPath, newPath).replace('/','-') || 'core'; + const searchRegExp = new RegExp('/', 'g'); + const prefix = relative(behatTempFeaturesPath, newPath).replace(searchRegExp,'-') || 'core'; const featureFilename = prefix + '-' + basename(featureFile); renameSync(featureFile, behatFeaturesPath + '/' + featureFilename); } diff --git a/scripts/templates/behat-plugin/classes/output/mobile.php b/scripts/templates/behat-plugin/classes/output/mobile.php index 88732ab38..bddc07bd8 100644 --- a/scripts/templates/behat-plugin/classes/output/mobile.php +++ b/scripts/templates/behat-plugin/classes/output/mobile.php @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -namespace local_moodlemobileapp\output; +namespace local_moodleappbehat\output; defined('MOODLE_INTERNAL') || die(); diff --git a/scripts/templates/behat-plugin/db/mobile.php b/scripts/templates/behat-plugin/db/mobile.php index 91b0def21..c829fa09d 100644 --- a/scripts/templates/behat-plugin/db/mobile.php +++ b/scripts/templates/behat-plugin/db/mobile.php @@ -16,7 +16,7 @@ // along with Moodle. If not, see . $addons = [ - 'local_moodlemobileapp' => [ + 'local_moodleappbehat' => [ 'handlers' => [ 'index' => [ 'delegate' => 'CoreMainMenuDelegate', @@ -28,7 +28,7 @@ $addons = [ ], ], 'lang' => [ - ['pluginname', 'local_moodlemobileapp'], + ['pluginname', 'local_moodleappbehat'], ], ], ]; diff --git a/tests/behat/app_behat_runtime.js b/tests/behat/app_behat_runtime.js index 19c3c7b75..9846e0cf1 100644 --- a/tests/behat/app_behat_runtime.js +++ b/tests/behat/app_behat_runtime.js @@ -601,7 +601,7 @@ case 'more menu': foundButton = findElementsBasedOnText({ text: 'More', - near: { text: 'Messages' }, + selector: 'ion-tab-button', })[0]; break; case 'user menu' : diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 5cc4eb45c..1bbc5ba55 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -15,7 +15,7 @@ // along with Moodle. If not, see . /** - * Mobile/desktop app steps definitions. + * Moodle App steps definitions. * * @package core * @category test @@ -49,7 +49,7 @@ interface behat_app_listener { } /** - * Mobile/desktop app steps definitions. + * Moodle App steps definitions. * * @package core * @category test @@ -518,7 +518,7 @@ class behat_app extends behat_base { $this->execute_script(" var script = document.createElement('script'); - script.src = '{$CFG->behat_wwwroot}/local/moodlemobileapp/tests/behat/app_behat_runtime.js'; + script.src = '{$CFG->behat_wwwroot}/local/moodleappbehat/tests/behat/app_behat_runtime.js'; document.body.append(script); "); diff --git a/tests/behat/classes/performance_measure.php b/tests/behat/classes/performance_measure.php index 4e3c8ee7d..f56125ae5 100644 --- a/tests/behat/classes/performance_measure.php +++ b/tests/behat/classes/performance_measure.php @@ -18,6 +18,8 @@ use Behat\Mink\Exception\DriverException; use Facebook\WebDriver\Exception\InvalidArgumentException; use Moodle\BehatExtension\Driver\WebDriver; +require_once(__DIR__ . '/../behat_app.php'); + /** * Performance measures for one particular metric. */ @@ -334,7 +336,7 @@ class performance_measure implements behat_app_listener { " ],", " ],", " ],", - ");", + "];", "", ]) ); From 22763cec084cea290297ba4b5b54300ee437a3c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 5 May 2022 12:56:08 +0200 Subject: [PATCH 204/220] MOBILE-4061 behat: Remove local plugin dependancy --- tests/behat/behat_app.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/behat/behat_app.php b/tests/behat/behat_app.php index 1bbc5ba55..ad12df796 100644 --- a/tests/behat/behat_app.php +++ b/tests/behat/behat_app.php @@ -353,17 +353,6 @@ class behat_app extends behat_base { $service->enabled = 1; $webservicemanager->update_external_service($service); } - - // If installed, also configure local_mobile plugin to enable additional features service. - $localplugins = core_component::get_plugin_list('local'); - if (array_key_exists('mobile', $localplugins)) { - $service = $webservicemanager->get_external_service_by_shortname( - 'local_mobile', MUST_EXIST); - if (!$service->enabled) { - $service->enabled = 1; - $webservicemanager->update_external_service($service); - } - } } /** From c1cc27e92963aece7809634e6d7fd94729dbd5af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 4 May 2022 10:46:59 +0200 Subject: [PATCH 205/220] MOBILE-4061 github: local_moodlemobileapp module is not needed anymore --- .github/workflows/performance.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 2652fda51..ad4589bca 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -19,7 +19,6 @@ jobs: - name: Additional checkouts run: | git clone --branch master --depth 1 https://github.com/moodle/moodle $GITHUB_WORKSPACE/moodle - git clone --branch integration --depth 1 https://github.com/moodlehq/moodle-local_moodlemobileapp $GITHUB_WORKSPACE/moodle/local/moodlemobileapp git clone --branch master --depth 1 https://github.com/moodlehq/moodle-docker $GITHUB_WORKSPACE/moodle-docker - name: Install npm packages run: | From 0457245db2d4e955ce37f4e7687c5e1266f0e5e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 4 May 2022 10:41:25 +0200 Subject: [PATCH 206/220] MOBILE-4061 github: Do not run performance on push --- .github/workflows/performance.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index ad4589bca..aafc955ec 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -1,6 +1,6 @@ name: Performance -on: [push, pull_request] +on: [ pull_request, workflow_dispatch ] jobs: performance: From f48885b822b1ec1d0f06904ba4e9b7971e38a604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 12 May 2022 15:38:29 +0200 Subject: [PATCH 207/220] MOBILE-4061 behat: Adapt tests to 3.9-4.0 LMS versions --- .../messages/tests/behat/basic_usage.feature | 1 + .../tests/behat/basic_usage-310.feature | 60 ++++++++ .../assign/tests/behat/basic_usage.feature | 1 + .../tests/behat/basic_usage-311.feature | 43 ++++++ .../choice/tests/behat/basic_usage.feature | 1 + .../mod/forum/tests/behat/basic_usage.feature | 1 + .../tests/behat/basic_usage-311.feature | 145 ++++++++++++++++++ .../course/tests/behat/basic_usage.feature | 2 + .../tests/behat/course_completion-310.feature | 34 ++++ .../tests/behat/course_completion.feature | 1 + .../course/tests/behat/courselist-311.feature | 121 +++++++++++++++ .../course/tests/behat/courselist.feature | 2 + .../tests/behat/basic_usage-310.feature | 84 ++++++++++ .../tests/behat/basic_usage-311.feature | 130 ++++++++++++++++ .../courses/tests/behat/basic_usage.feature | 1 + .../mainmenu/tests/behat/mainmenu-311.feature | 25 +++ .../mainmenu/tests/behat/mainmenu.feature | 3 + .../siteplugins/tests/behat/plugins.feature | 4 +- .../behat/navigation_externallinks.feature | 1 + 19 files changed, 658 insertions(+), 2 deletions(-) create mode 100755 src/addons/mod/assign/tests/behat/basic_usage-310.feature create mode 100755 src/addons/mod/choice/tests/behat/basic_usage-311.feature create mode 100755 src/core/features/course/tests/behat/basic_usage-311.feature create mode 100644 src/core/features/course/tests/behat/course_completion-310.feature create mode 100644 src/core/features/course/tests/behat/courselist-311.feature create mode 100755 src/core/features/courses/tests/behat/basic_usage-310.feature create mode 100755 src/core/features/courses/tests/behat/basic_usage-311.feature create mode 100644 src/core/features/mainmenu/tests/behat/mainmenu-311.feature diff --git a/src/addons/messages/tests/behat/basic_usage.feature b/src/addons/messages/tests/behat/basic_usage.feature index 3d2fe7489..638877888 100755 --- a/src/addons/messages/tests/behat/basic_usage.feature +++ b/src/addons/messages/tests/behat/basic_usage.feature @@ -112,6 +112,7 @@ Feature: Test basic usage of messages in app And I should find "hi" in the app And I should find "byee" in the app + # TODO Fix this test in all Moodle versions Scenario: User profile: send message, add/remove contact When I enter the app And I log in as "teacher1" diff --git a/src/addons/mod/assign/tests/behat/basic_usage-310.feature b/src/addons/mod/assign/tests/behat/basic_usage-310.feature new file mode 100755 index 000000000..2141af2b9 --- /dev/null +++ b/src/addons/mod/assign/tests/behat/basic_usage-310.feature @@ -0,0 +1,60 @@ +@mod @mod_assign @app @javascript @lms_upto3.10 +Feature: Test basic usage of assignment activity in app + In order to participate in the assignment while using the mobile app + I need basic assignment functionality to work + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student | student | student1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + And the following "activities" exist: + | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | duedate | attemptreopenmethod | + | assign | C1 | assign1 | assignment1 | Test assignment description1 | 1 | 1029844800 | manual | + + Scenario: View assign description, due date & View list of student submissions (as teacher) & View own submission or student submission + # Create, edit and submit as a student + When I enter the course "Course 1" as "student1" in the app + And I press "assignment1" in the app + Then the header should be "assignment1" in the app + And I should find "Test assignment description1" in the app + And I should find "Due date" in the app + And I should find "Tuesday, 20 August 2002, 12:00 PM" in the app + + When I press "Add submission" in the app + And I set the field "Online text submissions" to "Submission test" in the app + And I press "Save" in the app + Then I should find "Draft (not submitted)" in the app + And I should find "Not graded" in the app + + When I press "Edit submission" in the app + And I set the field "Online text submissions" to "Submission test edited" in the app + And I press "Save" in the app + And I press "OK" in the app + Then I should find "Submission test edited" in the app + + When I press "Submit assignment" in the app + And I press "OK" in the app + Then I should find "Submitted for grading" in the app + And I should find "Not graded" in the app + And I should find "Submission test edited" in the app + + # View as a teacher + When I enter the course "Course 1" as "teacher1" in the app + And I press "assignment1" in the app + Then the header should be "assignment1" in the app + + When I press "Submitted" in the app + Then I should find "Student student" in the app + And I should find "Not graded" in the app + + When I press "Student student" near "assignment1" in the app + Then I should find "Online text submissions" in the app + And I should find "Submission test edited" in the app diff --git a/src/addons/mod/assign/tests/behat/basic_usage.feature b/src/addons/mod/assign/tests/behat/basic_usage.feature index 1b084985a..f8521f987 100755 --- a/src/addons/mod/assign/tests/behat/basic_usage.feature +++ b/src/addons/mod/assign/tests/behat/basic_usage.feature @@ -19,6 +19,7 @@ Feature: Test basic usage of assignment activity in app | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | duedate | attemptreopenmethod | | assign | C1 | assign1 | assignment1 | Test assignment description1 | 1 | 1029844800 | manual | + @lms_from3.11 Scenario: View assign description, due date & View list of student submissions (as teacher) & View own submission or student submission # Create, edit and submit as a student When I enter the course "Course 1" as "student1" in the app diff --git a/src/addons/mod/choice/tests/behat/basic_usage-311.feature b/src/addons/mod/choice/tests/behat/basic_usage-311.feature new file mode 100755 index 000000000..c5c0c90d3 --- /dev/null +++ b/src/addons/mod/choice/tests/behat/basic_usage-311.feature @@ -0,0 +1,43 @@ +@mod @mod_choice @app @javascript @lms_upto3.11 +Feature: Test basic usage of choice activity in app + In order to participate in the choice while using the mobile app + As a student + I need basic choice functionality to work + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student | student | student1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + + Scenario: Download students choice in text format + # Submit answer as student + Given the following "activities" exist: + | activity | name | intro | course | idnumber | option | + | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | + And I enter the course "Course 1" as "student1" in the app + And I press "Choice name" in the app + And I select "Option 2" in the app + And I press "Save my choice" in the app + And I press "OK" in the app + + # Download answers as teacher + When I enter the course "Course 1" as "teacher1" in the app + And I press "Choice name" in the app + Then I should find "Test choice description" in the app + + When I press "Information" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "View 1 responses" + And I press "Download in text format" + # TODO Then I should find "..." in the downloads folder diff --git a/src/addons/mod/choice/tests/behat/basic_usage.feature b/src/addons/mod/choice/tests/behat/basic_usage.feature index 5de9ffaf8..73690ccc8 100755 --- a/src/addons/mod/choice/tests/behat/basic_usage.feature +++ b/src/addons/mod/choice/tests/behat/basic_usage.feature @@ -165,6 +165,7 @@ Feature: Test basic usage of choice activity in app But I should not find "This Choice has offline data to be synchronised." in the app # TODO remove LMS UI steps in app tests + @lms_from4.0 Scenario: Download students choice in text format # Submit answer as student Given the following "activities" exist: diff --git a/src/addons/mod/forum/tests/behat/basic_usage.feature b/src/addons/mod/forum/tests/behat/basic_usage.feature index 015ac7f08..88e7aef82 100755 --- a/src/addons/mod/forum/tests/behat/basic_usage.feature +++ b/src/addons/mod/forum/tests/behat/basic_usage.feature @@ -198,6 +198,7 @@ Feature: Test basic usage of forum activity in app And I press "Save changes" in the app Then I should find "There was a problem connecting to the site. Please check your connection and try again." in the app + # TODO Fix this test in all Moodle versions Scenario: Delete a forum post (only online) When I enter the course "Course 1" as "student1" in the app And I press "Test forum name" in the app diff --git a/src/core/features/course/tests/behat/basic_usage-311.feature b/src/core/features/course/tests/behat/basic_usage-311.feature new file mode 100755 index 000000000..2f56e7a6a --- /dev/null +++ b/src/core/features/course/tests/behat/basic_usage-311.feature @@ -0,0 +1,145 @@ +@mod @mod_course @app @javascript @lms_upto3.11 +Feature: Test basic usage of one course in app + In order to participate in one course while using the mobile app + As a student + I need basic course functionality to work + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student | student | student1@example.com | + | student2 | Student2 | student2 | student2@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | option | section | + | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 1 | + And the following "activities" exist: + | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | section | + | assign | C1 | assign1 | assignment | Test assignment description | 1 | 1 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | assessed | scale[modgrade_type] | + | forum | Test forum name | Test forum | C1 | forum | 0 | 5 | Point | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | section | + | chat | Test chat name | Test chat | C1 | chat | 0 | 2 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | section | + | data | Web links | Useful links | C1 | data1 | 4 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | section | + | lti | Test external name | Test external | C1 | external | 0 | 1 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | section | + | feedback | Test feedback name | Test feedback | C1 | feedback | 0 | 3 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | section | + | glossary | Test glossary | glossary description | C1 | gloss1 | 5 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | section | + | quiz | Quiz 1 | Quiz 1 description | C1 | quiz1 | 2 | + And the following "question categories" exist: + | contextlevel | reference | name | + | Course | C1 | Test questions | + And the following "questions" exist: + | questioncategory | qtype | name | questiontext | + | Test questions | truefalse | TF1 | Text of the first question | + | Test questions | truefalse | TF2 | Text of the second question | + And quiz "Quiz 1" contains the following questions: + | question | page | + | TF1 | 1 | + | TF2 | 2 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | section | + | survey | Test survey name | Test survey | C1 | survey | 0 | 1 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | + | wiki | Test wiki name | Test wiki | C1 | wiki | 0 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | section | + | lesson | Test lesson name | Test lesson | C1 | lesson | 0 | 3 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | section | + | scorm | Test scorm name | Test scorm | C1 | scorm | 0 | 2 | + And the following "activities" exist: + | activity | name | intro | course | idnumber | groupmode | section | + | workshop | Test workshop name | Test workshop | C1 | workshop | 0 | 3 | + + Scenario: Self enrol + Given I enter the course "Course 1" as "teacher1" in the app + And I press "Course summary" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "More..." + And I follow "Users" + And I follow "Enrolment methods" + And I click on "Enable" "icon" in the "Self enrolment (Student)" "table_row" + And I close the browser tab opened by the app + When I enter the app + And I log in as "student2" + And I press "Site home" in the app + And I press "Available courses" in the app + And I press "Course 1" in the app + And I press "Enrol me" in the app + And I press "OK" in the app + And I wait loading to finish in the app + Then the header should be "Course 1" in the app + And I should find "Choice course 1" in the app + And I should find "assignment" in the app + And I should find "Test forum name" in the app + And I should find "Test chat name" in the app + And I should find "Web links" in the app + And I should find "Test external name" in the app + And I should find "Test feedback name" in the app + And I should find "Test glossary" in the app + And I should find "Quiz 1" in the app + And I should find "Test survey name" in the app + And I should find "Test wiki name" in the app + And I should find "Test lesson name" in the app + And I should find "Test scorm name" in the app + And I should find "Test workshop name" in the app + + Scenario: Guest access + Given I enter the course "Course 1" as "teacher1" in the app + And I press "Course summary" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "More..." + And I follow "Users" + And I follow "Enrolment methods" + And I click on "Enable" "icon" in the "Guest access" "table_row" + And I close the browser tab opened by the app + When I enter the app + And I log in as "student2" + And I press "Site home" in the app + And I press "Available courses" in the app + And I press "Course 1" in the app + + Then I should find "Course summary" in the app + And I should find "Course" in the app + + When I press "View course" "ion-button" in the app + Then the header should be "Course 1" in the app + And I should find "Choice course 1" in the app + And I should find "assignment" in the app + And I should find "Test forum name" in the app + And I should find "Test chat name" in the app + And I should find "Web links" in the app + And I should find "Test feedback name" in the app + And I should find "Test glossary" in the app + And I should find "Quiz 1" in the app + And I should find "Test survey name" in the app + And I should find "Test wiki name" in the app + And I should find "Test lesson name" in the app + And I should find "Test scorm name" in the app + And I should find "Test workshop name" in the app diff --git a/src/core/features/course/tests/behat/basic_usage.feature b/src/core/features/course/tests/behat/basic_usage.feature index f1516594d..1674a661c 100755 --- a/src/core/features/course/tests/behat/basic_usage.feature +++ b/src/core/features/course/tests/behat/basic_usage.feature @@ -400,6 +400,7 @@ Feature: Test basic usage of one course in app And I should not find "Topic 1" in the app And I should not find "Topic 2" in the app + @lms_from4.0 Scenario: Self enrol Given I enter the course "Course 1" as "teacher1" in the app And I press "Course summary" in the app @@ -434,6 +435,7 @@ Feature: Test basic usage of one course in app And I should find "Test scorm name" in the app And I should find "Test workshop name" in the app + @lms_from4.0 Scenario: Guest access Given I enter the course "Course 1" as "teacher1" in the app And I press "Course summary" in the app diff --git a/src/core/features/course/tests/behat/course_completion-310.feature b/src/core/features/course/tests/behat/course_completion-310.feature new file mode 100644 index 000000000..60571703e --- /dev/null +++ b/src/core/features/course/tests/behat/course_completion-310.feature @@ -0,0 +1,34 @@ +@core @core_course @app @javascript @lms_upto3.10 +Feature: Check course completion feature. + In order to track the progress of the course on mobile device + As a student + I need to be able to update the activity completion status. + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | student1 | Student | 1 | student1@example.com | + And the following "courses" exist: + | fullname | shortname | category | enablecompletion | + | Course 1 | C1 | 0 | 1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + + Scenario: Activity completion, marking the checkbox manually + Given the following "activities" exist: + | activity | name | course | idnumber | completion | completionview | + | forum | First forum | C1 | forum1 | 1 | 0 | + | forum | Second forum | C1 | forum2 | 1 | 0 | + When I enter the course "Course 1" as "student1" in the app + # Set activities as completed. + And I should find "0%" in the app + And I click on "ion-button[title=\"Not completed: First forum. Select to mark as complete.\"]" "css" + And I should find "50%" in the app + And I click on "ion-button[title=\"Not completed: Second forum. Select to mark as complete.\"]" "css" + And I should find "100%" in the app + # Set activities as not completed. + And I click on "ion-button[title=\"Completed: First forum. Select to mark as not complete.\"]" "css" + And I should find "50%" in the app + And I click on "ion-button[title=\"Completed: Second forum. Select to mark as not complete.\"]" "css" + And I should find "0%" in the app diff --git a/src/core/features/course/tests/behat/course_completion.feature b/src/core/features/course/tests/behat/course_completion.feature index 999b55736..06ab51784 100644 --- a/src/core/features/course/tests/behat/course_completion.feature +++ b/src/core/features/course/tests/behat/course_completion.feature @@ -15,6 +15,7 @@ Feature: Check course completion feature. | user | course | role | | student1 | C1 | student | + @lms_from3.11 Scenario: Activity completion, marking the checkbox manually Given the following "activities" exist: | activity | name | course | idnumber | completion | completionview | diff --git a/src/core/features/course/tests/behat/courselist-311.feature b/src/core/features/course/tests/behat/courselist-311.feature new file mode 100644 index 000000000..0fd418c6d --- /dev/null +++ b/src/core/features/course/tests/behat/courselist-311.feature @@ -0,0 +1,121 @@ +@core @core_course @app @javascript @lms_upto3.11 +Feature: Test course list shown on app start tab + In order to select a course + As a student + I need to see the correct list of courses + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + | Course 2 | C2 | + And the following "users" exist: + | username | + | student1 | + | student2 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | student2 | C1 | student | + | student2 | C2 | student | + + Scenario: View courses (shortnames not displayed) + When I enter the app + And I log in as "student1" + Then I should find "Course 1" in the app + But I should not find "Course 2" in the app + But I should not find "C1" in the app + But I should not find "C2" in the app + + When I enter the app + And I log in as "student2" + Then I should find "Course 1" in the app + And I should find "Course 2" in the app + But I should not find "C1" in the app + But I should not find "C2" in the app + + Scenario: Filter courses + Given the following config values are set as admin: + | courselistshortnames | 1 | + And the following "courses" exist: + | fullname | shortname | + | Frog 3 | C3 | + | Frog 4 | C4 | + | Course 5 | C5 | + | Toad 6 | C6 | + And the following "course enrolments" exist: + | user | course | role | + | student2 | C3 | student | + | student2 | C4 | student | + | student2 | C5 | student | + | student2 | C6 | student | + # Create bogus courses so that the main ones aren't shown in the 'recently accessed' part. + # Because these come later in alphabetical order, they may not be displayed in the lower part + # which is OK. + And the following "courses" exist: + | fullname | shortname | + | Zogus 1 | Z1 | + | Zogus 2 | Z2 | + | Zogus 3 | Z3 | + | Zogus 4 | Z4 | + | Zogus 5 | Z5 | + | Zogus 6 | Z6 | + | Zogus 7 | Z7 | + | Zogus 8 | Z8 | + | Zogus 9 | Z9 | + | Zogus 10 | Z10 | + And the following "course enrolments" exist: + | user | course | role | + | student2 | Z1 | student | + | student2 | Z2 | student | + | student2 | Z3 | student | + | student2 | Z4 | student | + | student2 | Z5 | student | + | student2 | Z6 | student | + | student2 | Z7 | student | + | student2 | Z8 | student | + | student2 | Z9 | student | + | student2 | Z10 | student | + When I enter the app + And I log in as "student2" + Then I should find "C1" in the app + And I should find "C2" in the app + And I should find "C3" in the app + And I should find "C4" in the app + And I should find "C5" in the app + And I should find "C6" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Frog 3" in the app + And I should find "Frog 4" in the app + And I should find "Course 5" in the app + And I should find "Toad 6" in the app + + And I set the field "search text" to "fr" in the app + + Then I should find "C3" in the app + And I should find "C4" in the app + And I should find "Frog 3" in the app + And I should find "Frog 4" in the app + But I should not find "C1" in the app + And I should not find "C2" in the app + And I should not find "C5" in the app + And I should not find "C6" in the app + And I should not find "Course 1" in the app + And I should not find "Course 2" in the app + And I should not find "Course 5" in the app + And I should not find "Toad 6" in the app + + When I set the field "search text" to "" in the app + Then I should find "C1" in the app + And I should find "C2" in the app + And I should find "C3" in the app + And I should find "C4" in the app + And I should find "C5" in the app + And I should find "C6" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Frog 3" in the app + And I should find "Frog 4" in the app + And I should find "Course 5" in the app + And I should find "Toad 6" in the app diff --git a/src/core/features/course/tests/behat/courselist.feature b/src/core/features/course/tests/behat/courselist.feature index 7619ec85e..7d1807ac0 100644 --- a/src/core/features/course/tests/behat/courselist.feature +++ b/src/core/features/course/tests/behat/courselist.feature @@ -19,6 +19,7 @@ Feature: Test course list shown on app start tab | student2 | C1 | student | | student2 | C2 | student | + @lms_from4.0 Scenario: View courses (shortnames not displayed) When I enter the app And I log in as "student1" @@ -36,6 +37,7 @@ Feature: Test course list shown on app start tab But I should not find "C1" in the app But I should not find "C2" in the app + @lms_from4.0 Scenario: Filter courses Given the following config values are set as admin: | courselistshortnames | 1 | diff --git a/src/core/features/courses/tests/behat/basic_usage-310.feature b/src/core/features/courses/tests/behat/basic_usage-310.feature new file mode 100755 index 000000000..b22b47163 --- /dev/null +++ b/src/core/features/courses/tests/behat/basic_usage-310.feature @@ -0,0 +1,84 @@ +@mod @mod_courses @app @javascript @lms_upto3.10 +Feature: Test basic usage of courses in app + In order to participate in the courses while using the mobile app + As a student + I need basic courses functionality to work + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student | student | student1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + | Course 2 | C2 | 0 | + | Course 3 | C3 | 0 | + | Course 4 | C4 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | teacher1 | C2 | editingteacher | + | teacher1 | C3 | editingteacher | + | teacher1 | C4 | editingteacher | + | student1 | C1 | student | + | student1 | C2 | student | + | student1 | C3 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | option | + | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 2 | Test choice description | C2 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 3 | Test choice description | C3 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 4 | Test choice description | C4 | choice1 | Option 1, Option 2, Option 3 | + And the following "activities" exist: + | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | + | assign | C1 | assign1 | assignment | Test assignment description | 1 | + + Scenario: Links to actions in Timeline work for teachers/students + # Configure assignment as teacher + Given I enter the course "Course 1" as "teacher1" in the app + And I press "assignment" in the app + And I press "Information" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "Edit settings" + And I press "Expand all" + And I click on "duedate[enabled]" "checkbox" + And I click on "gradingduedate[enabled]" "checkbox" + And I press "Save and return to course" + And I close the browser tab opened by the app + + # Submit assignment as student + When I enter the app + And I log in as "student1" + Then I press "Open block drawer" in the app + And I press "Add submission" in the app + Then the header should be "assignment" in the app + And I should find "Test assignment description" in the app + And I should find "No attempt" in the app + And I should find "Due date" in the app + + When I press "Add submission" in the app + And I set the field "Online text submissions" to "test" in the app + And I press "Save" in the app + And I press "Submit assignment" in the app + And I press "OK" in the app + Then the header should be "assignment" in the app + And I should find "Test assignment description" in the app + And I should find "Submitted for grading" in the app + And I should find "Due date" in the app + + # Grade assignment as teacher + When I enter the app + And I log in as "teacher1" + Then I press "Open block drawer" in the app + And I press "Grade" in the app + Then the header should be "assignment" in the app + And I should find "Test assignment description" in the app + And I should find "Time remaining" in the app + + When I press "Needs grading" in the app + Then I should find "Student student" in the app + And I should find "Not graded" in the app diff --git a/src/core/features/courses/tests/behat/basic_usage-311.feature b/src/core/features/courses/tests/behat/basic_usage-311.feature new file mode 100755 index 000000000..1e543d0e3 --- /dev/null +++ b/src/core/features/courses/tests/behat/basic_usage-311.feature @@ -0,0 +1,130 @@ +@mod @mod_courses @app @javascript @lms_upto3.11 +Feature: Test basic usage of courses in app + In order to participate in the courses while using the mobile app + As a student + I need basic courses functionality to work + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | teacher | teacher1@example.com | + | student1 | Student | student | student1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + | Course 2 | C2 | 0 | + | Course 3 | C3 | 0 | + | Course 4 | C4 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | teacher1 | C2 | editingteacher | + | teacher1 | C3 | editingteacher | + | teacher1 | C4 | editingteacher | + | student1 | C1 | student | + | student1 | C2 | student | + | student1 | C3 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | option | + | choice | Choice course 1 | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 2 | Test choice description | C2 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 3 | Test choice description | C3 | choice1 | Option 1, Option 2, Option 3 | + | choice | Choice course 4 | Test choice description | C4 | choice1 | Option 1, Option 2, Option 3 | + And the following "activities" exist: + | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | + | assign | C1 | assign1 | assignment | Test assignment description | 1 | + + Scenario: "Dashboard" tab displayed in >= 3.3 sites + When I enter the app + And I log in as "student1" + Then I should see "Dashboard" + And the header should be "Acceptance test site" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Course 3" in the app + + When I press "Site home" in the app + Then I should find "Dashboard" in the app + And the header should be "Acceptance test site" in the app + + When I press "Dashboard" in the app + Then I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Course 3" in the app + + Scenario: See my courses + When I enter the app + And I log in as "student1" + Then the header should be "Acceptance test site" in the app + And I should find "Course 1" in the app + And I should find "Course 2" in the app + And I should find "Course 3" in the app + + When I press "Course 1" in the app + Then I should find "Choice course 1" in the app + And the header should be "Course 1" in the app + + When I press "Choice course 1" in the app + Then I should find "Test choice description" in the app + And the header should be "Choice course 1" in the app + + When I press the back button in the app + And I press the back button in the app + And I press "Course 2" in the app + Then I should find "Choice course 2" in the app + And the header should be "Course 2" in the app + + When I press the back button in the app + And I press "Course 3" in the app + Then I should find "Choice course 3" in the app + And the header should be "Course 3" in the app + + @lms_from3.11 + Scenario: Links to actions in Timeline work for teachers/students + # Configure assignment as teacher + Given I enter the course "Course 1" as "teacher1" in the app + And I press "assignment" in the app + And I press "Information" in the app + And I press "Open in browser" in the app + And I switch to the browser tab opened by the app + And I log in as "teacher1" + And I press "Actions menu" + And I follow "Edit settings" + And I press "Expand all" + And I click on "duedate[enabled]" "checkbox" + And I click on "gradingduedate[enabled]" "checkbox" + And I press "Save and return to course" + And I close the browser tab opened by the app + + # Submit assignment as student + When I enter the app + And I log in as "student1" + Then I press "Open block drawer" in the app + And I press "Add submission" in the app + Then the header should be "assignment" in the app + And I should find "Test assignment description" in the app + And I should find "No attempt" in the app + And I should find "Due:" in the app + + When I press "Add submission" in the app + And I set the field "Online text submissions" to "test" in the app + And I press "Save" in the app + And I press "Submit assignment" in the app + And I press "OK" in the app + Then the header should be "assignment" in the app + And I should find "Test assignment description" in the app + And I should find "Submitted for grading" in the app + And I should find "Due:" in the app + + # Grade assignment as teacher + When I enter the app + And I log in as "teacher1" + Then I press "Open block drawer" in the app + And I press "Grade" in the app + Then the header should be "assignment" in the app + And I should find "Test assignment description" in the app + And I should find "Time remaining" in the app + + When I press "Needs grading" in the app + Then I should find "Student student" in the app + And I should find "Not graded" in the app diff --git a/src/core/features/courses/tests/behat/basic_usage.feature b/src/core/features/courses/tests/behat/basic_usage.feature index fc59c4fbb..beab4df32 100755 --- a/src/core/features/courses/tests/behat/basic_usage.feature +++ b/src/core/features/courses/tests/behat/basic_usage.feature @@ -98,6 +98,7 @@ Feature: Test basic usage of courses in app And I should find "Course 3" in the app And I should find "Course 4" in the app + @lms_from4.0 # TODO remove LMS UI steps in app tests Scenario: Links to actions in Timeline work for teachers/students # Configure assignment as teacher diff --git a/src/core/features/mainmenu/tests/behat/mainmenu-311.feature b/src/core/features/mainmenu/tests/behat/mainmenu-311.feature new file mode 100644 index 000000000..955ff09ea --- /dev/null +++ b/src/core/features/mainmenu/tests/behat/mainmenu-311.feature @@ -0,0 +1,25 @@ +@app @javascript @lms_upto3.11 +Feature: Main Menu opens the right page + + Background: + Given the following "users" exist: + | username | + | student | + + Scenario: Opens Site Home when defaulthomepage is set to Site + Given the following config values are set as admin: + | defaulthomepage | 0 | + When I enter the app + And I log in as "student" + Then "Site home" should be selected in the app + And I should find "Available courses" in the app + And "Site home" "text" should appear before "Dashboard" "text" in the ".core-tabs-bar" "css_element" + + Scenario: Opens Dashboard when defaulthomepage is set to Dashboard + Given the following config values are set as admin: + | defaulthomepage | 1 | + When I enter the app + And I log in as "student" + Then "Dashboard" should be selected in the app + And I should find "Course overview" in the app + And "Dashboard" "text" should appear before "Site home" "text" in the ".core-tabs-bar" "css_element" diff --git a/src/core/features/mainmenu/tests/behat/mainmenu.feature b/src/core/features/mainmenu/tests/behat/mainmenu.feature index 421062ab2..704568a40 100644 --- a/src/core/features/mainmenu/tests/behat/mainmenu.feature +++ b/src/core/features/mainmenu/tests/behat/mainmenu.feature @@ -12,6 +12,7 @@ Feature: Main Menu opens the right page | user | course | role | | student | C1 | student | + @lms_from4.0 Scenario: Opens Site Home when defaulthomepage is set to Site Given the following config values are set as admin: | defaulthomepage | 0 | @@ -22,6 +23,7 @@ Feature: Main Menu opens the right page And "Site home" "text" should appear before "Dashboard" "text" in the ".core-tabs-bar" "css_element" And "Home" "text" should appear before "My courses" "text" in the ".mainmenu-tabs" "css_element" + @lms_from4.0 Scenario: Opens Dashboard when defaulthomepage is set to Dashboard Given the following config values are set as admin: | defaulthomepage | 1 | @@ -32,6 +34,7 @@ Feature: Main Menu opens the right page And "Dashboard" "text" should appear before "Site home" "text" in the ".core-tabs-bar" "css_element" And "Home" "text" should appear before "My courses" "text" in the ".mainmenu-tabs" "css_element" + @lms_from4.0 Scenario: Opens My Courses when defaulthomepage is set to My Courses Given the following config values are set as admin: | defaulthomepage | 3 | diff --git a/src/core/features/siteplugins/tests/behat/plugins.feature b/src/core/features/siteplugins/tests/behat/plugins.feature index 35d39f1ca..5055fc707 100644 --- a/src/core/features/siteplugins/tests/behat/plugins.feature +++ b/src/core/features/siteplugins/tests/behat/plugins.feature @@ -10,7 +10,7 @@ Feature: Plugins work properly. When I enter the app And I log in as "studentusername" And I press the more menu button in the app - Then I should find "Moodle Mobile language strings" in the app + Then I should find "Moodle App Behat (auto-generated)" in the app - When I press "Moodle Mobile language strings" in the app + When I press "Moodle App Behat (auto-generated)" in the app Then I should find "studentusername" in the app diff --git a/src/tests/behat/navigation_externallinks.feature b/src/tests/behat/navigation_externallinks.feature index e79737ac5..f49317ac2 100644 --- a/src/tests/behat/navigation_externallinks.feature +++ b/src/tests/behat/navigation_externallinks.feature @@ -18,6 +18,7 @@ Feature: It opens external links properly. | forum | user | name | message | | Test forum | student1 | Forum topic | See moodle.org external link | + # This test is flaky and may fail Scenario: Click an external link When I enter the course "Course 1" as "student1" in the app And I press "Test forum" in the app From 0fd5078cf9b57a18a9f6c126eb14181354529360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 5 May 2022 13:41:27 +0200 Subject: [PATCH 208/220] MOBILE-4061 behat: Group all moodleappbehat plugin files --- .../classes/output/mobile.php | 0 .../classes/privacy/provider.php | 0 .../db/mobile.php | 0 .../js/mobile/index.js | 0 .../lang/en/local_moodleappbehat.php | 0 .../tests}/behat/app_behat_runtime.js | 0 .../tests}/behat/behat_app.php | 0 .../tests}/behat/behat_performance.php | 0 .../behat/classes/performance_measure.php | 0 .../version.php | 0 scripts/build-behat-plugin.js | 23 ++++++++----------- 11 files changed, 10 insertions(+), 13 deletions(-) rename {scripts/templates/behat-plugin => local-moodleappbehat}/classes/output/mobile.php (100%) rename {scripts/templates/behat-plugin => local-moodleappbehat}/classes/privacy/provider.php (100%) rename {scripts/templates/behat-plugin => local-moodleappbehat}/db/mobile.php (100%) rename {scripts/templates/behat-plugin => local-moodleappbehat}/js/mobile/index.js (100%) rename {scripts/templates/behat-plugin => local-moodleappbehat}/lang/en/local_moodleappbehat.php (100%) rename {tests => local-moodleappbehat/tests}/behat/app_behat_runtime.js (100%) rename {tests => local-moodleappbehat/tests}/behat/behat_app.php (100%) rename {tests => local-moodleappbehat/tests}/behat/behat_performance.php (100%) rename {tests => local-moodleappbehat/tests}/behat/classes/performance_measure.php (100%) rename {scripts/templates/behat-plugin => local-moodleappbehat}/version.php (100%) diff --git a/scripts/templates/behat-plugin/classes/output/mobile.php b/local-moodleappbehat/classes/output/mobile.php similarity index 100% rename from scripts/templates/behat-plugin/classes/output/mobile.php rename to local-moodleappbehat/classes/output/mobile.php diff --git a/scripts/templates/behat-plugin/classes/privacy/provider.php b/local-moodleappbehat/classes/privacy/provider.php similarity index 100% rename from scripts/templates/behat-plugin/classes/privacy/provider.php rename to local-moodleappbehat/classes/privacy/provider.php diff --git a/scripts/templates/behat-plugin/db/mobile.php b/local-moodleappbehat/db/mobile.php similarity index 100% rename from scripts/templates/behat-plugin/db/mobile.php rename to local-moodleappbehat/db/mobile.php diff --git a/scripts/templates/behat-plugin/js/mobile/index.js b/local-moodleappbehat/js/mobile/index.js similarity index 100% rename from scripts/templates/behat-plugin/js/mobile/index.js rename to local-moodleappbehat/js/mobile/index.js diff --git a/scripts/templates/behat-plugin/lang/en/local_moodleappbehat.php b/local-moodleappbehat/lang/en/local_moodleappbehat.php similarity index 100% rename from scripts/templates/behat-plugin/lang/en/local_moodleappbehat.php rename to local-moodleappbehat/lang/en/local_moodleappbehat.php diff --git a/tests/behat/app_behat_runtime.js b/local-moodleappbehat/tests/behat/app_behat_runtime.js similarity index 100% rename from tests/behat/app_behat_runtime.js rename to local-moodleappbehat/tests/behat/app_behat_runtime.js diff --git a/tests/behat/behat_app.php b/local-moodleappbehat/tests/behat/behat_app.php similarity index 100% rename from tests/behat/behat_app.php rename to local-moodleappbehat/tests/behat/behat_app.php diff --git a/tests/behat/behat_performance.php b/local-moodleappbehat/tests/behat/behat_performance.php similarity index 100% rename from tests/behat/behat_performance.php rename to local-moodleappbehat/tests/behat/behat_performance.php diff --git a/tests/behat/classes/performance_measure.php b/local-moodleappbehat/tests/behat/classes/performance_measure.php similarity index 100% rename from tests/behat/classes/performance_measure.php rename to local-moodleappbehat/tests/behat/classes/performance_measure.php diff --git a/scripts/templates/behat-plugin/version.php b/local-moodleappbehat/version.php similarity index 100% rename from scripts/templates/behat-plugin/version.php rename to local-moodleappbehat/version.php diff --git a/scripts/build-behat-plugin.js b/scripts/build-behat-plugin.js index 810243ac6..1d0570d7b 100755 --- a/scripts/build-behat-plugin.js +++ b/scripts/build-behat-plugin.js @@ -46,23 +46,20 @@ async function main() { // Copy plugin template. const { version: appVersion } = require(projectPath('package.json')); - const templatePath = projectPath('scripts/templates/behat-plugin'); + const templatePath = projectPath('local-moodleappbehat'); + + + copySync(templatePath, pluginPath); + + // Update version.php + const pluginFilePath = pluginPath + '/version.php'; + const fileContents = readFileSync(pluginFilePath).toString(); + const replacements = { appVersion, pluginVersion: getMoodlePluginVersion(), }; - - copySync(templatePath, pluginPath); - - for await (const templateFilePath of getDirectoryFiles(templatePath)) { - const pluginFilePath = pluginPath + templateFilePath.substr(templatePath.length); - const fileContents = readFileSync(pluginFilePath).toString(); - - writeFileSync(pluginFilePath, replaceArguments(fileContents, replacements)); - } - - // Copy plugin files. - copySync(projectPath('tests/behat'), `${pluginPath}/tests/behat`); + writeFileSync(pluginFilePath, replaceArguments(fileContents, replacements)); // Copy feature files. const behatTempFeaturesPath = `${pluginPath}/behat-tmp`; From 8abfed60a62b59487c4367d849746997c5b61f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 12 May 2022 13:09:58 +0200 Subject: [PATCH 209/220] MOBILE-4061 behat: Github action to run Behat tests workflow --- .github/workflows/acceptance.yml | 65 ++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/workflows/acceptance.yml diff --git a/.github/workflows/acceptance.yml b/.github/workflows/acceptance.yml new file mode 100644 index 000000000..ba61f5aa3 --- /dev/null +++ b/.github/workflows/acceptance.yml @@ -0,0 +1,65 @@ +name: Behat tests + +on: + workflow_dispatch: + inputs: + tags: + description: 'Execute tags' + required: true + default: '~@performance' + moodle_branch: + description: 'Moodle branch' + required: true + default: 'master' + moodle_repository: + description: 'Moodle repository' + required: true + default: 'https://github.com/moodle/moodle' + +jobs: + behat: + runs-on: ubuntu-latest + env: + MOODLE_DOCKER_DB: pgsql + MOODLE_DOCKER_BROWSER: chrome + MOODLE_DOCKER_PHP_VERSION: 7.3 + steps: + - uses: actions/checkout@v2 + - id: nvmrc + uses: browniebroke/read-nvmrc-action@v1 + - uses: actions/setup-node@v1 + with: + node-version: '${{ steps.nvmrc.outputs.node_version }}' + - name: Additional checkouts + run: | + git clone --branch ${{ github.event.inputs.moodle_branch }} --depth 1 ${{ github.event.inputs.moodle_repository }} $GITHUB_WORKSPACE/moodle + git clone --branch master --depth 1 https://github.com/moodlehq/moodle-docker $GITHUB_WORKSPACE/moodle-docker + - name: Install npm packages + run: | + npm install -g npm@7 + npm ci --no-audit + - name: Generate Behat tests plugin + run: | + export MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle + npx gulp behat + - name: Configure & launch Moodle with Docker + run: | + export MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle + cp $GITHUB_WORKSPACE/moodle-docker/config.docker-template.php $GITHUB_WORKSPACE/moodle/config.php + sed -i "61i\$CFG->behat_ionic_wwwroot = 'http://moodleapp';" $GITHUB_WORKSPACE/moodle/config.php + $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose pull + $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose up -d + $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-wait-for-db + - name: Compile & launch production app with Docker + run: | + docker build -t moodlehq/moodleapp:behat . + docker run -d --rm --name moodleapp moodlehq/moodleapp:behat + docker network connect moodle-docker_default moodleapp --alias moodleapp + - name: Init Behat + run: | + export MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle + $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose exec -T webserver sh -c "php admin/tool/behat/cli/init.php" + - name: Run Behat tests + run: | + export MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle + $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose exec -T webserver sh -c "php admin/tool/behat/cli/run.php --verbose --tags='@app&&${{ github.event.inputs.tags }}' --auto-rerun" From 064ea15f8b58c96ec2fedcc74a4c676db96d580d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 12 May 2022 15:47:23 +0200 Subject: [PATCH 210/220] MOBILE-4061 behat: Include Behat runtime in the app --- gulpfile.js | 2 +- .../tests/behat/app_behat_runtime.js | 908 ------------------ .../tests/behat/behat_app.php | 86 +- src/app/app.module.ts | 2 + src/testing/behat-testing.module.prod.ts | 21 + src/testing/behat-testing.module.ts | 34 + src/testing/services/behat-blocking.ts | 241 +++++ src/testing/services/behat-dom.ts | 482 ++++++++++ src/testing/services/behat-runtime.ts | 391 ++++++++ 9 files changed, 1218 insertions(+), 949 deletions(-) delete mode 100644 local-moodleappbehat/tests/behat/app_behat_runtime.js create mode 100644 src/testing/behat-testing.module.prod.ts create mode 100644 src/testing/behat-testing.module.ts create mode 100644 src/testing/services/behat-blocking.ts create mode 100644 src/testing/services/behat-dom.ts create mode 100644 src/testing/services/behat-runtime.ts diff --git a/gulpfile.js b/gulpfile.js index 31db54239..7c7c5bb96 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -71,5 +71,5 @@ gulp.task('watch', () => { }); gulp.task('watch-behat', () => { - gulp.watch(['./tests/behat'], { interval: 500 }, gulp.parallel('behat')); + gulp.watch(['./src/**/*.feature', './local-moodleappbehat'], { interval: 500 }, gulp.parallel('behat')); }); diff --git a/local-moodleappbehat/tests/behat/app_behat_runtime.js b/local-moodleappbehat/tests/behat/app_behat_runtime.js deleted file mode 100644 index 9846e0cf1..000000000 --- a/local-moodleappbehat/tests/behat/app_behat_runtime.js +++ /dev/null @@ -1,908 +0,0 @@ -(function() { - // Set up the M object - only pending_js is implemented. - window.M = window.M ? window.M : {}; - const M = window.M; - M.util = M.util ? M.util : {}; - M.util.pending_js = M.util.pending_js ? M.util.pending_js : []; // eslint-disable-line camelcase - - /** - * Logs information from this Behat runtime JavaScript, including the time and the 'BEHAT' - * keyword so we can easily filter for it if needed. - * - * @param {string} text Information to log - */ - const log = function() { - const now = new Date(); - const nowFormatted = String(now.getHours()).padStart(2, '0') + ':' + - String(now.getMinutes()).padStart(2, '0') + ':' + - String(now.getSeconds()).padStart(2, '0') + '.' + - String(now.getMilliseconds()).padStart(2, '0'); - console.log('BEHAT: ' + nowFormatted, ...arguments); // eslint-disable-line no-console - }; - - /** - * Run after several setTimeouts to ensure queued events are finished. - * - * @param {function} target function to run - * @param {number} count Number of times to do setTimeout (leave blank for 10) - */ - const runAfterEverything = function(target, count) { - if (count === undefined) { - count = 10; - } - setTimeout(function() { - count--; - if (count == 0) { - target(); - } else { - runAfterEverything(target, count); - } - }, 0); - }; - - /** - * Adds a pending key to the array. - * - * @param {string} key Key to add - */ - const addPending = function(key) { - // Add a special DELAY entry whenever another entry is added. - if (window.M.util.pending_js.length == 0) { - window.M.util.pending_js.push('DELAY'); - } - window.M.util.pending_js.push(key); - - log('PENDING+: ' + window.M.util.pending_js); - }; - - /** - * Removes a pending key from the array. If this would clear the array, the actual clear only - * takes effect after the queued events are finished. - * - * @param {string} key Key to remove - */ - const removePending = function(key) { - // Remove the key immediately. - window.M.util.pending_js = window.M.util.pending_js.filter(function(x) { // eslint-disable-line camelcase - return x !== key; - }); - log('PENDING-: ' + window.M.util.pending_js); - - // If the only thing left is DELAY, then remove that as well, later... - if (window.M.util.pending_js.length === 1) { - runAfterEverything(function() { - // Check there isn't a spinner... - checkUIBlocked(); - - // Only remove it if the pending array is STILL empty after all that. - if (window.M.util.pending_js.length === 1) { - window.M.util.pending_js = []; // eslint-disable-line camelcase - log('PENDING-: ' + window.M.util.pending_js); - } - }); - } - }; - - /** - * Adds a pending key to the array, but removes it after some setTimeouts finish. - */ - const addPendingDelay = function() { - addPending('...'); - removePending('...'); - }; - - // Override XMLHttpRequest to mark things pending while there is a request waiting. - const realOpen = XMLHttpRequest.prototype.open; - let requestIndex = 0; - XMLHttpRequest.prototype.open = function() { - const index = requestIndex++; - const key = 'httprequest-' + index; - - try { - // Add to the list of pending requests. - addPending(key); - - // Detect when it finishes and remove it from the list. - this.addEventListener('loadend', function() { - removePending(key); - }); - - return realOpen.apply(this, arguments); - } catch (error) { - removePending(key); - throw error; - } - }; - - let waitingBlocked = false; - - /** - * Checks if a loading spinner is present and visible; if so, adds it to the pending array - * (and if not, removes it). - */ - const checkUIBlocked = function() { - const blocked = document.querySelector('span.core-loading-spinner, ion-loading, .click-block-active'); - if (blocked && blocked.offsetParent) { - if (!waitingBlocked) { - addPending('blocked'); - waitingBlocked = true; - } - } else { - if (waitingBlocked) { - removePending('blocked'); - waitingBlocked = false; - } - } - }; - - // It would be really beautiful if you could detect CSS transitions and animations, that would - // cover almost everything, but sadly there is no way to do this because the transitionstart - // and animationcancel events are not implemented in Chrome, so we cannot detect either of - // these reliably. Instead, we have to look for any DOM changes and do horrible polling. Most - // of the animations are set to 500ms so we allow it to continue from 500ms after any DOM - // change. - - let recentMutation = false; - let lastMutation; - - /** - * Called from the mutation callback to remove the pending tag after 500ms if nothing else - * gets mutated. - * - * This will be called after 500ms, then every 100ms until there have been no mutation events - * for 500ms. - */ - const pollRecentMutation = function() { - if (Date.now() - lastMutation > 500) { - recentMutation = false; - removePending('dom-mutation'); - } else { - setTimeout(pollRecentMutation, 100); - } - }; - - /** - * Mutation callback, called whenever the DOM is mutated. - */ - const mutationCallback = function() { - lastMutation = Date.now(); - if (!recentMutation) { - recentMutation = true; - addPending('dom-mutation'); - setTimeout(pollRecentMutation, 500); - } - // Also update the spinner presence if needed. - checkUIBlocked(); - }; - - // Set listener using the mutation callback. - const observer = new MutationObserver(mutationCallback); - observer.observe(document, {attributes: true, childList: true, subtree: true}); - - /** - * Check if an element is visible. - * - * @param {HTMLElement} element Element - * @param {HTMLElement} container Container - * @returns {boolean} Whether the element is visible or not - */ - const isElementVisible = (element, container) => { - if (element.getAttribute('aria-hidden') === 'true' || getComputedStyle(element).display === 'none') - return false; - - const parentElement = getParentElement(element); - if (parentElement === container) - return true; - - if (!parentElement) - return false; - - return isElementVisible(parentElement, container); - }; - - /** - * Check if an element is selected. - * - * @param {HTMLElement} element Element - * @param {HTMLElement} container Container - * @returns {boolean} Whether the element is selected or not - */ - const isElementSelected = (element, container) => { - const ariaCurrent = element.getAttribute('aria-current'); - if ( - (ariaCurrent && ariaCurrent !== 'false') || - (element.getAttribute('aria-selected') === 'true') || - (element.getAttribute('aria-checked') === 'true') - ) - return true; - - const parentElement = getParentElement(element); - if (!parentElement || parentElement === container) - return false; - - return isElementSelected(parentElement, container); - }; - - /** - * Finds elements within a given container with exact info. - * - * @param {HTMLElement} container Parent element to search the element within - * @param {string} text Text to look for - * @return {Array} Elements containing the given text with exact boolean. - */ - const findElementsBasedOnTextWithinWithExact = (container, text) => { - const elements = []; - const attributesSelector = `[aria-label*="${text}"], a[title*="${text}"], img[alt*="${text}"]`; - - for (const foundByAttributes of container.querySelectorAll(attributesSelector)) { - if (!isElementVisible(foundByAttributes, container)) - continue; - - const exact = foundByAttributes.title == text || foundByAttributes.alt == text || foundByAttributes.ariaLabel == text; - elements.push({ element: foundByAttributes, exact: exact }); - } - - const treeWalker = document.createTreeWalker( - container, - NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_DOCUMENT_FRAGMENT | NodeFilter.SHOW_TEXT, - { - acceptNode: node => { - if ( - node instanceof HTMLStyleElement || - node instanceof HTMLLinkElement || - node instanceof HTMLScriptElement - ) - return NodeFilter.FILTER_REJECT; - - if ( - node instanceof HTMLElement && ( - node.getAttribute('aria-hidden') === 'true' || getComputedStyle(node).display === 'none' - ) - ) - return NodeFilter.FILTER_REJECT; - - return NodeFilter.FILTER_ACCEPT; - } - }, - ); - - let currentNode; - while (currentNode = treeWalker.nextNode()) { - if (currentNode instanceof Text) { - if (currentNode.textContent.includes(text)) { - elements.push({ element: currentNode.parentElement, exact: currentNode.textContent.trim() == text }); - } - - continue; - } - - const labelledBy = currentNode.getAttribute('aria-labelledby'); - const labelElement = labelledBy && container.querySelector(`#${labelledBy}`); - if (labelElement && labelElement.innerText && labelElement.innerText.includes(text)) { - elements.push({ element: currentNode, exact: labelElement.innerText.trim() == text }); - - continue; - } - - if (currentNode.shadowRoot) { - for (const childNode of currentNode.shadowRoot.childNodes) { - if ( - !(childNode instanceof HTMLElement) || ( - childNode instanceof HTMLStyleElement || - childNode instanceof HTMLLinkElement || - childNode instanceof HTMLScriptElement - ) - ) { - continue; - } - - if (childNode.matches(attributesSelector)) { - const exact = childNode.title == text || childNode.alt == text || childNode.ariaLabel == text; - elements.push({ element: childNode, exact: exact}); - - continue; - } - - elements.push(...findElementsBasedOnTextWithinWithExact(childNode, text)); - } - } - } - - return elements; - }; - - /** - * Finds elements within a given container. - * - * @param {HTMLElement} container Parent element to search the element within. - * @param {string} text Text to look for. - * @return {HTMLElement[]} Elements containing the given text. - */ - const findElementsBasedOnTextWithin = (container, text) => { - const elements = findElementsBasedOnTextWithinWithExact(container, text); - - // Give more relevance to exact matches. - elements.sort((a, b) => { - return b.exact - a.exact; - }); - - return elements.map(element => element.element); - }; - - /** - * Given a list of elements, get the top ancestors among all of them. - * - * This will remote duplicates and drop any elements nested within each other. - * - * @param {Array} elements Elements list. - * @return {Array} Top ancestors. - */ - const getTopAncestors = function(elements) { - const uniqueElements = new Set(elements); - - for (const element of uniqueElements) { - for (otherElement of uniqueElements) { - if (otherElement === element) { - continue; - } - - if (element.contains(otherElement)) { - uniqueElements.delete(otherElement); - } - } - } - - return Array.from(uniqueElements); - }; - - /** - * Get parent element, including Shadow DOM parents. - * - * @param {HTMLElement} element Element. - * @return {HTMLElement} Parent element. - */ - const getParentElement = function(element) { - return element.parentElement || (element.getRootNode() && element.getRootNode().host) || null; - }; - - /** - * Get closest element matching a selector, without traversing up a given container. - * - * @param {HTMLElement} element Element. - * @param {string} selector Selector. - * @param {HTMLElement} container Topmost container to search within. - * @return {HTMLElement} Closest matching element. - */ - const getClosestMatching = function(element, selector, container) { - if (element.matches(selector)) { - return element; - } - - if (element === container || !element.parentElement) { - return null; - } - - return getClosestMatching(element.parentElement, selector, container); - }; - - /** - * Function to find top container element. - * - * @param {string} containerName Whether to search inside the a container name. - * @return {HTMLElement} Found top container element. - */ - const getCurrentTopContainerElement = function (containerName) { - let topContainer; - let containers; - - switch (containerName) { - case 'html': - containers = document.querySelectorAll('html'); - break; - case 'toast': - containers = document.querySelectorAll('ion-app ion-toast.hydrated'); - containers = Array.from(containers).map(container => container.shadowRoot.querySelector('.toast-container')); - break; - case 'alert': - containers = document.querySelectorAll('ion-app ion-alert.hydrated'); - break; - case 'action-sheet': - containers = document.querySelectorAll('ion-app ion-action-sheet.hydrated'); - break; - case 'modal': - containers = document.querySelectorAll('ion-app ion-modal.hydrated'); - break; - case 'popover': - containers = document.querySelectorAll('ion-app ion-popover.hydrated'); - break; - case 'user-tour': - containers = document.querySelectorAll('core-user-tours-user-tour.is-active'); - break; - default: - // Other containerName or not implemented. - const containerSelector = 'ion-alert, ion-popover, ion-action-sheet, ion-modal, core-user-tours-user-tour.is-active, page-core-mainmenu, ion-app'; - containers = document.querySelectorAll(containerSelector); - } - - if (containers.length > 0) { - // Get the one with more zIndex. - topContainer = Array.from(containers).reduce((a, b) => { - return getComputedStyle(a).zIndex > getComputedStyle(b).zIndex ? a : b; - }, containers[0]); - } - - if (containerName == 'page' || containerName == 'split-view content') { - // Find non hidden pages inside the container. - let pageContainers = topContainer.querySelectorAll('.ion-page:not(.ion-page-hidden)'); - pageContainers = Array.from(pageContainers).filter((page) => { - return !page.closest('.ion-page.ion-page-hidden'); - }); - - if (pageContainers.length > 0) { - // Get the more general one to avoid failing. - topContainer = pageContainers[0]; - } - - if (containerName == 'split-view content') { - topContainer = topContainer.querySelector('core-split-view ion-router-outlet'); - } - } - - return topContainer; - } - - /** - * Function to find elements based on their text or Aria label. - * - * @param {object} locator Element locator. - * @param {string} containerName Whether to search only inside a specific container. - * @return {HTMLElement} Found elements - */ - const findElementsBasedOnText = function(locator, containerName) { - let topContainer = getCurrentTopContainerElement(containerName); - - let container = topContainer; - - if (locator.within) { - const withinElements = findElementsBasedOnText(locator.within); - - if (withinElements.length === 0) { - throw new Error('There was no match for within text') - } else if (withinElements.length > 1) { - const withinElementsAncestors = getTopAncestors(withinElements); - - if (withinElementsAncestors.length > 1) { - throw new Error('Too many matches for within text'); - } - - topContainer = container = withinElementsAncestors[0]; - } else { - topContainer = container = withinElements[0]; - } - } - - if (topContainer && locator.near) { - const nearElements = findElementsBasedOnText(locator.near); - - if (nearElements.length === 0) { - throw new Error('There was no match for near text') - } else if (nearElements.length > 1) { - const nearElementsAncestors = getTopAncestors(nearElements); - - if (nearElementsAncestors.length > 1) { - throw new Error('Too many matches for near text'); - } - - container = getParentElement(nearElementsAncestors[0]); - } else { - container = getParentElement(nearElements[0]); - } - } - - do { - const elements = findElementsBasedOnTextWithin(container, locator.text); - const filteredElements = locator.selector - ? elements.map(element => getClosestMatching(element, locator.selector, container)).filter(element => !!element) - : elements; - - if (filteredElements.length > 0) { - return filteredElements; - } - } while (container !== topContainer && (container = getParentElement(container)) && container !== topContainer); - - return []; - }; - - /** - * Make sure that an element is visible and wait to trigger the callback. - * - * @param {HTMLElement} element Element. - * @param {Function} callback Callback called when the element is visible, passing bounding box parameter. - */ - const ensureElementVisible = function(element, callback) { - const initialRect = element.getBoundingClientRect(); - - element.scrollIntoView(false); - - requestAnimationFrame(function () { - const rect = element.getBoundingClientRect(); - - if (initialRect.y !== rect.y) { - setTimeout(function () { - callback(rect); - }, 300); - addPendingDelay(); - - return; - } - - callback(rect); - }); - - addPendingDelay(); - }; - - /** - * Press an element. - * - * @param {HTMLElement} element Element to press. - */ - const pressElement = function(element) { - ensureElementVisible(element, function(rect) { - // Simulate a mouse click on the button. - const eventOptions = { - clientX: rect.left + rect.width / 2, - clientY: rect.top + rect.height / 2, - bubbles: true, - view: window, - cancelable: true, - }; - - // Events don't bubble up across Shadow DOM boundaries, and some buttons - // may not work without doing this. - const parentElement = getParentElement(element); - - if (parentElement && parentElement.matches('ion-button, ion-back-button')) { - element = parentElement; - } - - // There are some buttons in the app that don't respond to click events, for example - // buttons using the core-supress-events directive. That's why we need to send both - // click and mouse events. - element.dispatchEvent(new MouseEvent('mousedown', eventOptions)); - - setTimeout(() => { - element.dispatchEvent(new MouseEvent('mouseup', eventOptions)); - element.click(); - }, 300); - - // Mark busy until the button click finishes processing. - addPendingDelay(); - }); - }; - - /** - * Function to find and click an app standard button. - * - * @param {string} button Type of button to press - * @return {string} OK if successful, or ERROR: followed by message - */ - const behatPressStandard = function(button) { - log('Action - Click standard button: ' + button); - - // Find button - let foundButton = null; - - switch (button) { - case 'back': - foundButton = findElementsBasedOnText({ text: 'Back' })[0]; - break; - case 'main menu': // Deprecated name. - case 'more menu': - foundButton = findElementsBasedOnText({ - text: 'More', - selector: 'ion-tab-button', - })[0]; - break; - case 'user menu' : - foundButton = findElementsBasedOnText({ text: 'User account' })[0]; - break; - case 'page menu': - foundButton = findElementsBasedOnText({ text: 'Display options' })[0]; - break; - default: - return 'ERROR: Unsupported standard button type'; - } - - // Click button - pressElement(foundButton); - - return 'OK'; - }; - - /** - * When there is a popup, clicks on the backdrop. - * - * @return {string} OK if successful, or ERROR: followed by message - */ - const behatClosePopup = function() { - log('Action - Close popup'); - - let backdrops = Array.from(document.querySelectorAll('ion-backdrop')); - backdrops = backdrops.filter(function(backdrop) { - return !!backdrop.offsetParent; - }); - - if (!backdrops.length) { - return 'ERROR: Could not find backdrop'; - } - if (backdrops.length > 1) { - return 'ERROR: Found too many backdrops'; - } - const backdrop = backdrops[0]; - backdrop.click(); - - // Mark busy until the click finishes processing. - addPendingDelay(); - - return 'OK'; - }; - - /** - * Function to find an arbitrary element based on its text or aria label. - * - * @param {object} locator Element locator. - * @param {string} containerName Whether to search only inside a specific container content. - * @return {string} OK if successful, or ERROR: followed by message - */ - const behatFind = function(locator, containerName) { - log('Action - Find', { locator, containerName }); - - try { - const element = findElementsBasedOnText(locator, containerName)[0]; - - if (!element) { - return 'ERROR: No matches for text'; - } - - log('Action - Found', { locator, containerName, element }); - return 'OK'; - } catch (error) { - return 'ERROR: ' + error.message; - } - }; - - /** - * Scroll an element into view. - * - * @param {object} locator Element locator. - * @return {string} OK if successful, or ERROR: followed by message - */ - const behatScrollTo = function(locator) { - log('Action - scrollTo', { locator }); - - try { - let element = findElementsBasedOnText(locator)[0]; - - if (!element) { - return 'ERROR: No matches for text'; - } - - element = element.closest('ion-item') ?? element.closest('button') ?? element; - - element.scrollIntoView(); - - log('Action - Scrolled to', { locator, element }); - return 'OK'; - } catch (error) { - return 'ERROR: ' + error.message; - } - } - - /** - * Load more items form an active list with infinite loader. - * - * @return {string} OK if successful, or ERROR: followed by message - */ - const behatLoadMoreItems = async function() { - log('Action - loadMoreItems'); - - try { - const infiniteLoading = Array - .from(document.querySelectorAll('core-infinite-loading')) - .find(element => !element.closest('.ion-page-hidden')); - - if (!infiniteLoading) { - return 'ERROR: There isn\'t an infinite loader in the current page'; - } - - const initialOffset = infiniteLoading.offsetTop; - const isLoading = () => !!infiniteLoading.querySelector('ion-spinner[aria-label]'); - const isCompleted = () => !isLoading() && !infiniteLoading.querySelector('ion-button'); - const hasMoved = () => infiniteLoading.offsetTop !== initialOffset; - - if (isCompleted()) { - return 'ERROR: All items are already loaded'; - } - - infiniteLoading.scrollIntoView({ behavior: 'smooth' }); - - // Wait 100ms - await new Promise(resolve => setTimeout(resolve, 100)); - - if (isLoading() || isCompleted() || hasMoved()) { - return 'OK'; - } - - infiniteLoading.querySelector('ion-button').click(); - - // Wait 100ms - await new Promise(resolve => setTimeout(resolve, 100)); - - return (isLoading() || isCompleted() || hasMoved()) ? 'OK' : 'ERROR: Couldn\'t load more items'; - } catch (error) { - return 'ERROR: ' + error.message; - } - } - - /** - * Check whether an item is selected or not. - * - * @param {object} locator Element locator. - * @return {string} YES or NO if successful, or ERROR: followed by message - */ - const behatIsSelected = function(locator) { - log('Action - Is Selected', locator); - - try { - const element = findElementsBasedOnText(locator)[0]; - - return isElementSelected(element, document.body) ? 'YES' : 'NO'; - } catch (error) { - return 'ERROR: ' + error.message; - } - } - - /** - * Function to press arbitrary item based on its text or Aria label. - * - * @param {object} locator Element locator. - * @return {string} OK if successful, or ERROR: followed by message - */ - const behatPress = function(locator) { - log('Action - Press', locator); - - let found; - try { - found = findElementsBasedOnText(locator)[0]; - - if (!found) { - return 'ERROR: No matches for text'; - } - } catch (error) { - return 'ERROR: ' + error.message; - } - - pressElement(found); - - return 'OK'; - }; - - /** - * Gets the currently displayed page header. - * - * @return {string} OK: followed by header text if successful, or ERROR: followed by message. - */ - const behatGetHeader = function() { - log('Action - Get header'); - - let titles = Array.from(document.querySelectorAll('.ion-page:not(.ion-page-hidden) > ion-header h1')); - titles = titles.filter(function(title) { - return isElementVisible(title, document.body); - }); - - if (titles.length > 1) { - return 'ERROR: Too many possible titles'; - } else if (!titles.length) { - return 'ERROR: No title found'; - } else { - const title = titles[0].innerText.trim(); - return 'OK:' + title; - } - }; - - /** - * Sets the text of a field to the specified value. - * - * This currently matches fields only based on the placeholder attribute. - * - * @param {string} field Field name - * @param {string} value New value - * @return {string} OK or ERROR: followed by message - */ - const behatSetField = function(field, value) { - log('Action - Set field ' + field + ' to: ' + value); - - const found = findElementsBasedOnText({ text: field, selector: 'input, textarea, [contenteditable="true"]' })[0]; - if (!found) { - return 'ERROR: No matches for text'; - } - - // Functions to get/set value depending on field type. - let setValue; - let getValue; - switch (found.nodeName) { - case 'INPUT': - case 'TEXTAREA': - setValue = function(text) { - found.value = text; - }; - getValue = function() { - return found.value; - }; - break; - case 'DIV': - setValue = function(text) { - found.innerHTML = text; - }; - getValue = function() { - return found.innerHTML; - }; - break; - } - - // Pretend we have cut and pasted the new text. - let event; - if (getValue() !== '') { - event = new InputEvent('input', {bubbles: true, view: window, cancelable: true, - inputType: 'devareByCut'}); - setTimeout(function() { - setValue(''); - found.dispatchEvent(event); - }, 0); - } - if (value !== '') { - event = new InputEvent('input', {bubbles: true, view: window, cancelable: true, - inputType: 'insertFromPaste', data: value}); - setTimeout(function() { - setValue(value); - found.dispatchEvent(event); - }, 0); - } - - return 'OK'; - }; - - /** - * Get an Angular component instance. - * - * @param {string} selector Element selector - * @param {string} className Constructor class name - * @return {object} Component instance - */ - const behatGetAngularInstance = function(selector, className) { - log('Action - Get Angular instance ' + selector + ', ' + className); - - const activeElement = Array.from(document.querySelectorAll(`.ion-page:not(.ion-page-hidden) ${selector}`)).pop(); - - if (!activeElement || !activeElement.__ngContext__) { - return null; - } - - return activeElement.__ngContext__.find(node => node?.constructor?.name === className); - }; - - // Make some functions publicly available for Behat to call. - window.behat = { - pressStandard : behatPressStandard, - closePopup : behatClosePopup, - find : behatFind, - scrollTo : behatScrollTo, - loadMoreItems: behatLoadMoreItems, - isSelected : behatIsSelected, - press : behatPress, - setField : behatSetField, - getHeader : behatGetHeader, - getAngularInstance: behatGetAngularInstance, - }; -})(); diff --git a/local-moodleappbehat/tests/behat/behat_app.php b/local-moodleappbehat/tests/behat/behat_app.php index ad12df796..e17c9e1fd 100644 --- a/local-moodleappbehat/tests/behat/behat_app.php +++ b/local-moodleappbehat/tests/behat/behat_app.php @@ -72,6 +72,8 @@ class behat_app extends behat_base { /** @var array Config overrides */ protected $appconfig = ['disableUserTours' => true]; + protected $windowsize = '360x720'; + /** * Register listener. * @@ -147,7 +149,13 @@ class behat_app extends behat_base { public function i_wait_the_app_to_restart() { // Wait window to reload. $this->spin(function() { - return $this->evaluate_script("return !window.behat;"); + $result = $this->evaluate_script("return !window.behat;"); + + if (!$result) { + throw new DriverException('Window is not reloading properly.'); + } + + return true; }); // Prepare testing runtime again. @@ -164,15 +172,14 @@ class behat_app extends behat_base { */ public function i_find_in_the_app(bool $not, string $locator, string $containerName = '') { $locator = $this->parse_element_locator($locator); - $locatorjson = json_encode($locator); if (!empty($containerName)) { preg_match('/^ inside the (.+)$/', $containerName, $matches); $containerName = $matches[1]; } $containerName = json_encode($containerName); - $this->spin(function() use ($not, $locatorjson, $containerName) { - $result = $this->evaluate_script("return window.behat.find($locatorjson, $containerName);"); + $this->spin(function() use ($not, $locator, $containerName) { + $result = $this->evaluate_script("return window.behat.find($locator, $containerName);"); if ($not && $result === 'OK') { throw new DriverException('Error, found an item that should not be found'); @@ -196,10 +203,9 @@ class behat_app extends behat_base { */ public function i_scroll_to_in_the_app(string $locator) { $locator = $this->parse_element_locator($locator); - $locatorjson = json_encode($locator); - $this->spin(function() use ($locatorjson) { - $result = $this->evaluate_script("return window.behat.scrollTo($locatorjson);"); + $this->spin(function() use ($locator) { + $result = $this->evaluate_script("return window.behat.scrollTo($locator);"); if ($result !== 'OK') { throw new DriverException('Error finding item - ' . $result); @@ -224,7 +230,7 @@ class behat_app extends behat_base { $this->spin(function() use ($not) { $result = $this->evaluate_async_script('return window.behat.loadMoreItems();'); - if ($not && $result !== 'ERROR: All items are already loaded') { + if ($not && $result !== 'ERROR: All items are already loaded.') { throw new DriverException('It should not have been possible to load more items'); } @@ -247,7 +253,7 @@ class behat_app extends behat_base { public function i_swipe_in_the_app(string $direction) { $method = 'swipe' . ucwords($direction); - $this->evaluate_script("behat.getAngularInstance('ion-content', 'CoreSwipeNavigationDirective').$method()"); + $this->evaluate_script("window.behat.getAngularInstance('ion-content', 'CoreSwipeNavigationDirective').$method()"); // Wait swipe animation to finish. $this->getSession()->wait(300); @@ -262,10 +268,9 @@ class behat_app extends behat_base { */ public function be_selected_in_the_app(string $locator, bool $not = false) { $locator = $this->parse_element_locator($locator); - $locatorjson = json_encode($locator); - $this->spin(function() use ($locatorjson, $not) { - $result = $this->evaluate_script("return window.behat.isSelected($locatorjson);"); + $this->spin(function() use ($locator, $not) { + $result = $this->evaluate_script("return window.behat.isSelected($locator);"); switch ($result) { case 'YES': @@ -347,8 +352,8 @@ class behat_app extends behat_base { // Enable mobile service. require_once($CFG->dirroot . '/webservice/lib.php'); $webservicemanager = new webservice(); - $service = $webservicemanager->get_external_service_by_shortname( - MOODLE_OFFICIAL_MOBILE_SERVICE, MUST_EXIST); + $service = $webservicemanager->get_external_service_by_shortname(MOODLE_OFFICIAL_MOBILE_SERVICE, MUST_EXIST); + if (!$service->enabled) { $service->enabled = 1; $webservicemanager->update_external_service($service); @@ -474,7 +479,7 @@ class behat_app extends behat_base { // Restart the browser and set its size. $this->getSession()->restart(); - $this->resize_window('360x720', true); + $this->resize_window($this->windowsize, true); if (empty($this->ionicurl)) { $this->ionicurl = $this->start_or_reuse_ionic(); @@ -502,14 +507,13 @@ class behat_app extends behat_base { throw new DriverException('Moodle app not found in browser'); }, false, 60); - // Inject Behat JavaScript runtime. - global $CFG; + try { + // Init Behat JavaScript runtime. + $this->execute_script('window.behatInit();'); + } catch (Exception $error) { + throw new DriverException('Moodle app not running or not running on Automated mode.'); + } - $this->execute_script(" - var script = document.createElement('script'); - script.src = '{$CFG->behat_wwwroot}/local/moodleappbehat/tests/behat/app_behat_runtime.js'; - document.body.append(script); - "); if ($restart) { // Assert initial page. @@ -609,11 +613,11 @@ class behat_app extends behat_base { $this->login($username); } - $mycoursesfound = $this->evaluate_script("return window.behat.find({ text: 'My courses', near: { text: 'Messages' } });"); + $mycoursesfound = $this->evaluate_script("return window.behat.find({ text: 'My courses', selector: 'ion-tab-button'});"); if ($mycoursesfound !== 'OK') { // My courses not present enter from Dashboard. - $this->i_press_in_the_app('"Home" near "Messages"'); + $this->i_press_in_the_app('"Home" "ion-tab-button"'); $this->i_press_in_the_app('"Dashboard"'); $this->i_press_in_the_app('"'.$coursename.'" near "Course overview"'); @@ -622,7 +626,7 @@ class behat_app extends behat_base { return; } - $this->i_press_in_the_app('"My courses" near "Messages"'); + $this->i_press_in_the_app('"My courses" "ion-tab-button"'); $this->i_press_in_the_app('"'.$coursename.'"'); $this->wait_for_pending_js(); @@ -777,10 +781,9 @@ class behat_app extends behat_base { */ public function i_press_in_the_app(string $locator) { $locator = $this->parse_element_locator($locator); - $locatorjson = json_encode($locator); - $this->spin(function() use ($locatorjson) { - $result = $this->evaluate_script("return window.behat.press($locatorjson);"); + $this->spin(function() use ($locator) { + $result = $this->evaluate_script("return window.behat.press($locator);"); if ($result !== 'OK') { throw new DriverException('Error pressing item - ' . $result); @@ -807,27 +810,26 @@ class behat_app extends behat_base { public function i_select_in_the_app(string $selectedtext, string $locator) { $selected = $selectedtext === 'select' ? 'YES' : 'NO'; $locator = $this->parse_element_locator($locator); - $locatorjson = json_encode($locator); - $this->spin(function() use ($selectedtext, $selected, $locatorjson) { + $this->spin(function() use ($selectedtext, $selected, $locator) { // Don't do anything if the item is already in the expected state. - $result = $this->evaluate_script("return window.behat.isSelected($locatorjson);"); + $result = $this->evaluate_script("return window.behat.isSelected($locator);"); if ($result === $selected) { return true; } // Press item. - $result = $this->evaluate_script("return window.behat.press($locatorjson);"); + $result = $this->evaluate_script("return window.behat.press($locator);"); if ($result !== 'OK') { throw new DriverException('Error pressing item - ' . $result); } // Check that it worked as expected. - usleep(1000000); + $this->wait_for_pending_js(); - $result = $this->evaluate_script("return window.behat.isSelected($locatorjson);"); + $result = $this->evaluate_script("return window.behat.isSelected($locator);"); switch ($result) { case 'YES': @@ -1045,7 +1047,7 @@ class behat_app extends behat_base { $this->getSession()->switchToWindow($names[1]); } - $this->execute_script('window.close()'); + $this->execute_script('window.close();'); $this->getSession()->switchToWindow($names[0]); } @@ -1064,10 +1066,14 @@ class behat_app extends behat_base { * Parse an element locator string. * * @param string $text Element locator string. - * @return object + * @return JSON of the locator. */ - public function parse_element_locator(string $text): object { - preg_match('/^"((?:[^"]|\\")*?)"(?: "([^"]*?)")?(?: (near|within) "((?:[^"]|\\")*?)"(?: "([^"]*?)")?)?$/', $text, $matches); + public function parse_element_locator(string $text): string { + preg_match( + '/^"((?:[^"]|\\")*?)"(?: "([^"]*?)")?(?: (near|within) "((?:[^"]|\\")*?)"(?: "([^"]*?)")?)?$/', + $text, + $matches + ); $locator = [ 'text' => str_replace('\\"', '"', $matches[1]), @@ -1081,7 +1087,7 @@ class behat_app extends behat_base { ]; } - return (object) $locator; + return json_encode((object) $locator); } /** @@ -1143,7 +1149,7 @@ class behat_app extends behat_base { } /** - * Evaludate a script that returns a Promise. + * Evaluate a script that returns a Promise. * * @param string $script * @return mixed Resolved promise result. diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 6ae88d2a5..82928a691 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -32,6 +32,7 @@ import { JitCompilerFactory } from '@angular/platform-browser-dynamic'; import { CoreCronDelegate } from '@services/cron'; import { CoreSiteInfoCronHandler } from '@services/handlers/site-info-cron'; import { moodleTransitionAnimation } from '@classes/page-transition'; +import { BehatTestingModule } from '@/testing/behat-testing.module'; // For translate loader. AoT requires an exported function for factories. export function createTranslateLoader(http: HttpClient): TranslateHttpLoader { @@ -59,6 +60,7 @@ export function createTranslateLoader(http: HttpClient): TranslateHttpLoader { AppRoutingModule, CoreModule, AddonsModule, + BehatTestingModule, ], providers: [ { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, diff --git a/src/testing/behat-testing.module.prod.ts b/src/testing/behat-testing.module.prod.ts new file mode 100644 index 000000000..a95d24c81 --- /dev/null +++ b/src/testing/behat-testing.module.prod.ts @@ -0,0 +1,21 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { NgModule } from '@angular/core'; + +/** + * Stub used in production to avoid including testing code in production bundles. + */ +@NgModule({}) +export class BehatTestingModule {} diff --git a/src/testing/behat-testing.module.ts b/src/testing/behat-testing.module.ts new file mode 100644 index 000000000..11bfde709 --- /dev/null +++ b/src/testing/behat-testing.module.ts @@ -0,0 +1,34 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { CoreAppProvider } from '@services/app'; +import { TestsBehatBlockingService } from './services/behat-blocking'; +import { BehatTestsWindow, TestsBehatRuntime } from './services/behat-runtime'; + +function initializeBehatTestsWindow(window: BehatTestsWindow) { + // Make functions publicly available for Behat to call. + window.behatInit = TestsBehatRuntime.init; +} + +@NgModule({ + providers: + CoreAppProvider.isAutomated() + ? [ + { provide: APP_INITIALIZER, multi: true, useValue: () => initializeBehatTestsWindow(window) }, + TestsBehatBlockingService, + ] + : [], +}) +export class BehatTestingModule {} diff --git a/src/testing/services/behat-blocking.ts b/src/testing/services/behat-blocking.ts new file mode 100644 index 000000000..dbffa5a16 --- /dev/null +++ b/src/testing/services/behat-blocking.ts @@ -0,0 +1,241 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Injectable } from '@angular/core'; +import { makeSingleton } from '@singletons'; +import { BehatTestsWindow, TestsBehatRuntime } from './behat-runtime'; + +/** + * Behat block JS manager. + */ +@Injectable({ providedIn: 'root' }) +export class TestsBehatBlockingService { + + protected waitingBlocked = false; + protected recentMutation = false; + protected lastMutation = 0; + protected initialized = false; + + /** + * Listen to mutations and override XML Requests. + */ + init(): void { + if (this.initialized) { + return; + } + + this.initialized = true; + this.listenToMutations(); + this.xmlRequestOverride(); + + const win = window as BehatTestsWindow; + + // Set up the M object - only pending_js is implemented. + win.M = win.M ?? {}; + win.M.util = win.M.util ?? {}; + win.M.util.pending_js = win.M.util.pending_js ?? []; + + TestsBehatRuntime.log('Initialized!'); + } + + /** + * Get pending list on window M object. + */ + protected get pendingList(): string[] { + const win = window as BehatTestsWindow; + + return win.M?.util?.pending_js || []; + } + + /** + * Set pending list on window M object. + */ + protected set pendingList(values: string[]) { + const win = window as BehatTestsWindow; + + if (!win.M?.util?.pending_js) { + return; + } + + win.M.util.pending_js = values; + } + + /** + * Adds a pending key to the array. + * + * @param key Key to add. + */ + block(key: string): void { + // Add a special DELAY entry whenever another entry is added. + if (this.pendingList.length === 0) { + this.pendingList.push('DELAY'); + } + this.pendingList.push(key); + + TestsBehatRuntime.log('PENDING+: ' + this.pendingList); + } + + /** + * Removes a pending key from the array. If this would clear the array, the actual clear only + * takes effect after the queued events are finished. + * + * @param key Key to remove + */ + unblock(key: string): void { + // Remove the key immediately. + this.pendingList = this.pendingList.filter((x) => x !== key); + + TestsBehatRuntime.log('PENDING-: ' + this.pendingList); + + // If the only thing left is DELAY, then remove that as well, later... + if (this.pendingList.length === 1) { + this.runAfterEverything(() => { + // Check there isn't a spinner... + this.checkUIBlocked(); + + // Only remove it if the pending array is STILL empty after all that. + if (this.pendingList.length === 1) { + this.pendingList = []; + TestsBehatRuntime.log('PENDING-: ' + this.pendingList); + } + }); + } + } + + /** + * Adds a pending key to the array, but removes it after some setTimeouts finish. + */ + delay(): void { + this.block('...'); + this.unblock('...'); + } + + /** + * Run after several setTimeouts to ensure queued events are finished. + * + * @param target Function to run. + * @param count Number of times to do setTimeout (leave blank for 10). + */ + protected runAfterEverything(target: () => void, count = 10): void { + setTimeout(() => { + count--; + if (count === 0) { + target(); + + return; + } + this.runAfterEverything(target, count); + }, 0); + } + + /** + * It would be really beautiful if you could detect CSS transitions and animations, that would + * cover almost everything, but sadly there is no way to do this because the transitionstart + * and animationcancel events are not implemented in Chrome, so we cannot detect either of + * these reliably. Instead, we have to look for any DOM changes and do horrible polling. Most + * of the animations are set to 500ms so we allow it to continue from 500ms after any DOM + * change. + */ + protected listenToMutations(): void { + // Set listener using the mutation callback. + const observer = new MutationObserver(() => { + this.lastMutation = Date.now(); + + if (!this.recentMutation) { + this.recentMutation = true; + this.block('dom-mutation'); + + setTimeout(() => { + this.pollRecentMutation(); + }, 500); + } + + // Also update the spinner presence if needed. + this.checkUIBlocked(); + }); + + observer.observe(document, { attributes: true, childList: true, subtree: true }); + } + + /** + * Called from the mutation callback to remove the pending tag after 500ms if nothing else + * gets mutated. + * + * This will be called after 500ms, then every 100ms until there have been no mutation events + * for 500ms. + */ + protected pollRecentMutation(): void { + if (Date.now() - this.lastMutation > 500) { + this.recentMutation = false; + this.unblock('dom-mutation'); + + return; + } + + setTimeout(() => { + this.pollRecentMutation(); + }, 100); + } + + /** + * Checks if a loading spinner is present and visible; if so, adds it to the pending array + * (and if not, removes it). + */ + protected checkUIBlocked(): void { + const blocked = document.querySelector('span.core-loading-spinner, ion-loading, .click-block-active'); + + if (blocked?.offsetParent) { + if (!this.waitingBlocked) { + this.block('blocked'); + this.waitingBlocked = true; + } + } else { + if (this.waitingBlocked) { + this.unblock('blocked'); + this.waitingBlocked = false; + } + } + } + + /** + * Override XMLHttpRequest to mark things pending while there is a request waiting. + */ + protected xmlRequestOverride(): void { + const realOpen = XMLHttpRequest.prototype.open; + let requestIndex = 0; + + XMLHttpRequest.prototype.open = function(...args) { + const index = requestIndex++; + const key = 'httprequest-' + index; + + try { + // Add to the list of pending requests. + TestsBehatBlocking.block(key); + + // Detect when it finishes and remove it from the list. + this.addEventListener('loadend', () => { + TestsBehatBlocking.unblock(key); + }); + + return realOpen.apply(this, args); + } catch (error) { + TestsBehatBlocking.unblock(key); + throw error; + } + }; + } + +} + +export const TestsBehatBlocking = makeSingleton(TestsBehatBlockingService); diff --git a/src/testing/services/behat-dom.ts b/src/testing/services/behat-dom.ts new file mode 100644 index 000000000..eff06ab61 --- /dev/null +++ b/src/testing/services/behat-dom.ts @@ -0,0 +1,482 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { TestsBehatBlocking } from './behat-blocking'; +import { TestBehatElementLocator } from './behat-runtime'; + +/** + * Behat Dom Utils helper functions. + */ +export class TestsBehatDomUtils { + + /** + * Check if an element is visible. + * + * @param element Element. + * @param container Container. + * @return Whether the element is visible or not. + */ + static isElementVisible(element: HTMLElement, container: HTMLElement): boolean { + if (element.getAttribute('aria-hidden') === 'true' || getComputedStyle(element).display === 'none') { + return false; + } + + const parentElement = this.getParentElement(element); + if (parentElement === container) { + return true; + } + + if (!parentElement) { + return false; + } + + return this.isElementVisible(parentElement, container); + } + + /** + * Check if an element is selected. + * + * @param element Element. + * @param container Container. + * @return Whether the element is selected or not. + */ + static isElementSelected(element: HTMLElement, container: HTMLElement): boolean { + const ariaCurrent = element.getAttribute('aria-current'); + if ( + (ariaCurrent && ariaCurrent !== 'false') || + (element.getAttribute('aria-selected') === 'true') || + (element.getAttribute('aria-checked') === 'true') + ) { + return true; + } + + const parentElement = this.getParentElement(element); + if (!parentElement || parentElement === container) { + return false; + } + + return this.isElementSelected(parentElement, container); + }; + + /** + * Finds elements within a given container with exact info. + * + * @param container Parent element to search the element within + * @param text Text to look for + * @return Elements containing the given text with exact boolean. + */ + protected static findElementsBasedOnTextWithinWithExact(container: HTMLElement, text: string): ElementsWithExact[] { + const attributesSelector = `[aria-label*="${text}"], a[title*="${text}"], img[alt*="${text}"]`; + + const elements = Array.from(container.querySelectorAll(attributesSelector)) + .filter((element => this.isElementVisible(element, container))) + .map((element) => { + const exact = this.checkElementLabel(element, text); + + return { element, exact }; + }); + + const treeWalker = document.createTreeWalker( + container, + NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_DOCUMENT_FRAGMENT | NodeFilter.SHOW_TEXT, // eslint-disable-line no-bitwise + { + acceptNode: node => { + if (node instanceof HTMLStyleElement || + node instanceof HTMLLinkElement || + node instanceof HTMLScriptElement) { + return NodeFilter.FILTER_REJECT; + } + + if (node instanceof HTMLElement && + (node.getAttribute('aria-hidden') === 'true' || getComputedStyle(node).display === 'none')) { + return NodeFilter.FILTER_REJECT; + } + + return NodeFilter.FILTER_ACCEPT; + }, + }, + ); + + let currentNode: Node | null = null; + // eslint-disable-next-line no-cond-assign + while (currentNode = treeWalker.nextNode()) { + if (currentNode instanceof Text) { + if (currentNode.textContent?.includes(text) && currentNode.parentElement) { + elements.push({ + element: currentNode.parentElement, + exact: currentNode.textContent.trim() === text, + }); + } + + continue; + } + + if (currentNode instanceof HTMLElement) { + const labelledBy = currentNode.getAttribute('aria-labelledby'); + const labelElement = labelledBy && container.querySelector(`#${labelledBy}`); + if (labelElement && labelElement.innerText && labelElement.innerText.includes(text)) { + elements.push({ + element: currentNode, + exact: labelElement.innerText.trim() == text, + }); + + continue; + } + } + + if (currentNode instanceof Element && currentNode.shadowRoot) { + for (const childNode of Array.from(currentNode.shadowRoot.childNodes)) { + if (!(childNode instanceof HTMLElement) || ( + childNode instanceof HTMLStyleElement || + childNode instanceof HTMLLinkElement || + childNode instanceof HTMLScriptElement)) { + continue; + } + + if (childNode.matches(attributesSelector)) { + elements.push({ + element: childNode, + exact: this.checkElementLabel(childNode, text), + }); + + continue; + } + + elements.push(...this.findElementsBasedOnTextWithinWithExact(childNode, text)); + } + } + } + + return elements; + }; + + /** + * Checks an element has exactly the same label (title, alt or aria-label). + * + * @param element Element to check. + * @param text Text to check. + * @return If text matches any of the label attributes. + */ + protected static checkElementLabel(element: HTMLElement, text: string): boolean { + return element.title === text || + element.getAttribute('alt') === text || + element.getAttribute('aria-label') === text; + } + + /** + * Finds elements within a given container. + * + * @param container Parent element to search the element within. + * @param text Text to look for. + * @return Elements containing the given text. + */ + protected static findElementsBasedOnTextWithin(container: HTMLElement, text: string): HTMLElement[] { + const elements = this.findElementsBasedOnTextWithinWithExact(container, text); + + // Give more relevance to exact matches. + elements.sort((a, b) => Number(b.exact) - Number(a.exact)); + + return elements.map(element => element.element); + }; + + /** + * Given a list of elements, get the top ancestors among all of them. + * + * This will remote duplicates and drop any elements nested within each other. + * + * @param elements Elements list. + * @return Top ancestors. + */ + protected static getTopAncestors(elements: HTMLElement[]): HTMLElement[] { + const uniqueElements = new Set(elements); + + for (const element of uniqueElements) { + for (const otherElement of uniqueElements) { + if (otherElement === element) { + continue; + } + + if (element.contains(otherElement)) { + uniqueElements.delete(otherElement); + } + } + } + + return Array.from(uniqueElements); + }; + + /** + * Get parent element, including Shadow DOM parents. + * + * @param element Element. + * @return Parent element. + */ + protected static getParentElement(element: HTMLElement): HTMLElement | null { + return element.parentElement || + (element.getRootNode() && (element.getRootNode() as ShadowRoot).host as HTMLElement) || + null; + } + + /** + * Get closest element matching a selector, without traversing up a given container. + * + * @param element Element. + * @param selector Selector. + * @param container Topmost container to search within. + * @return Closest matching element. + */ + protected static getClosestMatching(element: HTMLElement, selector: string, container: HTMLElement | null): HTMLElement | null { + if (element.matches(selector)) { + return element; + } + + if (element === container || !element.parentElement) { + return null; + } + + return this.getClosestMatching(element.parentElement, selector, container); + }; + + /** + * Function to find top container element. + * + * @param containerName Whether to search inside the a container name. + * @return Found top container element. + */ + protected static getCurrentTopContainerElement(containerName: string): HTMLElement | null { + let topContainer: HTMLElement | null = null; + let containers: HTMLElement[] = []; + const nonImplementedSelectors = + 'ion-alert, ion-popover, ion-action-sheet, ion-modal, core-user-tours-user-tour.is-active, page-core-mainmenu, ion-app'; + + switch (containerName) { + case 'html': + containers = Array.from(document.querySelectorAll('html')); + break; + case 'toast': + containers = Array.from(document.querySelectorAll('ion-app ion-toast.hydrated')); + containers = containers.map(container => container?.shadowRoot?.querySelector('.toast-container') || container); + break; + case 'alert': + containers = Array.from(document.querySelectorAll('ion-app ion-alert.hydrated')); + break; + case 'action-sheet': + containers = Array.from(document.querySelectorAll('ion-app ion-action-sheet.hydrated')); + break; + case 'modal': + containers = Array.from(document.querySelectorAll('ion-app ion-modal.hydrated')); + break; + case 'popover': + containers = Array.from(document.querySelectorAll('ion-app ion-popover.hydrated')); + break; + case 'user-tour': + containers = Array.from(document.querySelectorAll('core-user-tours-user-tour.is-active')); + break; + default: + // Other containerName or not implemented. + containers = Array.from(document.querySelectorAll(nonImplementedSelectors)); + } + + if (containers.length > 0) { + // Get the one with more zIndex. + topContainer = + containers.reduce((a, b) => getComputedStyle(a).zIndex > getComputedStyle(b).zIndex ? a : b, containers[0]); + } + + if (!topContainer) { + return null; + } + + if (containerName == 'page' || containerName == 'split-view content') { + // Find non hidden pages inside the container. + let pageContainers = Array.from(topContainer.querySelectorAll('.ion-page:not(.ion-page-hidden)')); + pageContainers = pageContainers.filter((page) => !page.closest('.ion-page.ion-page-hidden')); + + if (pageContainers.length > 0) { + // Get the more general one to avoid failing. + topContainer = pageContainers[0]; + } + + if (containerName == 'split-view content') { + topContainer = topContainer.querySelector('core-split-view ion-router-outlet'); + } + } + + return topContainer; + }; + + /** + * Function to find element based on their text or Aria label. + * + * @param locator Element locator. + * @param containerName Whether to search only inside a specific container. + * @return First found element. + */ + static findElementBasedOnText(locator: TestBehatElementLocator, containerName = ''): HTMLElement { + return this.findElementsBasedOnText(locator, containerName)[0]; + } + + /** + * Function to find elements based on their text or Aria label. + * + * @param locator Element locator. + * @param containerName Whether to search only inside a specific container. + * @return Found elements + */ + protected static findElementsBasedOnText(locator: TestBehatElementLocator, containerName = ''): HTMLElement[] { + let topContainer = this.getCurrentTopContainerElement(containerName); + + let container = topContainer; + + if (locator.within) { + const withinElements = this.findElementsBasedOnText(locator.within); + + if (withinElements.length === 0) { + throw new Error('There was no match for within text'); + } else if (withinElements.length > 1) { + const withinElementsAncestors = this.getTopAncestors(withinElements); + + if (withinElementsAncestors.length > 1) { + throw new Error('Too many matches for within text'); + } + + topContainer = container = withinElementsAncestors[0]; + } else { + topContainer = container = withinElements[0]; + } + } + + if (topContainer && locator.near) { + const nearElements = this.findElementsBasedOnText(locator.near); + + if (nearElements.length === 0) { + throw new Error('There was no match for near text'); + } else if (nearElements.length > 1) { + const nearElementsAncestors = this.getTopAncestors(nearElements); + + if (nearElementsAncestors.length > 1) { + throw new Error('Too many matches for near text'); + } + + container = this.getParentElement(nearElementsAncestors[0]); + } else { + container = this.getParentElement(nearElements[0]); + } + } + + do { + if (!container) { + break; + } + + const elements = this.findElementsBasedOnTextWithin(container, locator.text); + + let filteredElements: HTMLElement[] = elements; + + if (locator.selector) { + filteredElements = []; + const selector = locator.selector; + + elements.forEach((element) => { + const closest = this.getClosestMatching(element, selector, container); + if (closest) { + filteredElements.push(closest); + } + }); + } + + if (filteredElements.length > 0) { + return filteredElements; + } + + } while (container !== topContainer && (container = this.getParentElement(container)) && container !== topContainer); + + return []; + }; + + /** + * Make sure that an element is visible and wait to trigger the callback. + * + * @param element Element. + * @param callback Callback called when the element is visible, passing bounding box parameter. + */ + protected static ensureElementVisible(element: HTMLElement, callback: (rect: DOMRect) => void): void { + const initialRect = element.getBoundingClientRect(); + + element.scrollIntoView(false); + + requestAnimationFrame(() => { + const rect = element.getBoundingClientRect(); + + if (initialRect.y !== rect.y) { + setTimeout(() => { + callback(rect); + }, 300); + + TestsBehatBlocking.delay(); + + return; + } + + callback(rect); + }); + + TestsBehatBlocking.delay(); + }; + + /** + * Press an element. + * + * @param element Element to press. + */ + static pressElement(element: HTMLElement): void { + this.ensureElementVisible(element, (rect) => { + // Simulate a mouse click on the button. + const eventOptions = { + clientX: rect.left + rect.width / 2, + clientY: rect.top + rect.height / 2, + bubbles: true, + view: window, + cancelable: true, + }; + + // Events don't bubble up across Shadow DOM boundaries, and some buttons + // may not work without doing this. + const parentElement = this.getParentElement(element); + + if (parentElement && parentElement.matches('ion-button, ion-back-button')) { + element = parentElement; + } + + // There are some buttons in the app that don't respond to click events, for example + // buttons using the core-supress-events directive. That's why we need to send both + // click and mouse events. + element.dispatchEvent(new MouseEvent('mousedown', eventOptions)); + + setTimeout(() => { + element.dispatchEvent(new MouseEvent('mouseup', eventOptions)); + element.click(); + }, 300); + + // Mark busy until the button click finishes processing. + TestsBehatBlocking.delay(); + }); + } + +} + +type ElementsWithExact = { + element: HTMLElement; + exact: boolean; +}; diff --git a/src/testing/services/behat-runtime.ts b/src/testing/services/behat-runtime.ts new file mode 100644 index 000000000..a13bb61a1 --- /dev/null +++ b/src/testing/services/behat-runtime.ts @@ -0,0 +1,391 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { TestsBehatDomUtils } from './behat-dom'; +import { TestsBehatBlocking } from './behat-blocking'; + +/** + * Behat runtime servive with public API. + */ +export class TestsBehatRuntime { + + static init(): void { + TestsBehatBlocking.init(); + + (window as BehatTestsWindow).behat = { + closePopup: TestsBehatRuntime.closePopup, + find: TestsBehatRuntime.find, + getAngularInstance: TestsBehatRuntime.getAngularInstance, + getHeader: TestsBehatRuntime.getHeader, + isSelected: TestsBehatRuntime.isSelected, + loadMoreItems: TestsBehatRuntime.loadMoreItems, + log: TestsBehatRuntime.log, + press: TestsBehatRuntime.press, + pressStandard: TestsBehatRuntime.pressStandard, + scrollTo: TestsBehatRuntime.scrollTo, + setField: TestsBehatRuntime.setField, + }; + } + + /** + * Function to find and click an app standard button. + * + * @param button Type of button to press + * @return OK if successful, or ERROR: followed by message + */ + static pressStandard(button: string): string { + this.log('Action - Click standard button: ' + button); + + // Find button + let foundButton: HTMLElement | undefined; + + switch (button) { + case 'back': + foundButton = TestsBehatDomUtils.findElementBasedOnText({ text: 'Back' }); + break; + case 'main menu': // Deprecated name. + case 'more menu': + foundButton = TestsBehatDomUtils.findElementBasedOnText({ + text: 'More', + selector: 'ion-tab-button', + }); + break; + case 'user menu' : + foundButton = TestsBehatDomUtils.findElementBasedOnText({ text: 'User account' }); + break; + case 'page menu': + foundButton = TestsBehatDomUtils.findElementBasedOnText({ text: 'Display options' }); + break; + default: + return 'ERROR: Unsupported standard button type'; + } + + if (!foundButton) { + return `ERROR: Button '${button}' not found`; + } + + // Click button + TestsBehatDomUtils.pressElement(foundButton); + + return 'OK'; + } + + /** + * When there is a popup, clicks on the backdrop. + * + * @return OK if successful, or ERROR: followed by message + */ + static closePopup(): string { + this.log('Action - Close popup'); + + let backdrops = Array.from(document.querySelectorAll('ion-backdrop')); + backdrops = backdrops.filter((backdrop) => !!backdrop.offsetParent); + + if (!backdrops.length) { + return 'ERROR: Could not find backdrop'; + } + if (backdrops.length > 1) { + return 'ERROR: Found too many backdrops'; + } + const backdrop = backdrops[0]; + backdrop.click(); + + // Mark busy until the click finishes processing. + TestsBehatBlocking.delay(); + + return 'OK'; + } + + /** + * Function to find an arbitrary element based on its text or aria label. + * + * @param locator Element locator. + * @param containerName Whether to search only inside a specific container content. + * @return OK if successful, or ERROR: followed by message + */ + static find(locator: TestBehatElementLocator, containerName: string): string { + this.log('Action - Find', { locator, containerName }); + + try { + const element = TestsBehatDomUtils.findElementBasedOnText(locator, containerName); + + if (!element) { + return 'ERROR: No element matches locator to find.'; + } + + this.log('Action - Found', { locator, containerName, element }); + + return 'OK'; + } catch (error) { + return 'ERROR: ' + error.message; + } + } + + /** + * Scroll an element into view. + * + * @param locator Element locator. + * @return OK if successful, or ERROR: followed by message + */ + static scrollTo(locator: TestBehatElementLocator): string { + this.log('Action - scrollTo', { locator }); + + try { + let element = TestsBehatDomUtils.findElementBasedOnText(locator); + + if (!element) { + return 'ERROR: No element matches element to scroll to.'; + } + + element = element.closest('ion-item') ?? element.closest('button') ?? element; + + element.scrollIntoView(); + + this.log('Action - Scrolled to', { locator, element }); + + return 'OK'; + } catch (error) { + return 'ERROR: ' + error.message; + } + } + + /** + * Load more items form an active list with infinite loader. + * + * @return OK if successful, or ERROR: followed by message + */ + static async loadMoreItems(): Promise { + this.log('Action - loadMoreItems'); + + try { + const infiniteLoading = Array + .from(document.querySelectorAll('core-infinite-loading')) + .find(element => !element.closest('.ion-page-hidden')); + + if (!infiniteLoading) { + return 'ERROR: There isn\'t an infinite loader in the current page.'; + } + + const initialOffset = infiniteLoading.offsetTop; + const isLoading = () => !!infiniteLoading.querySelector('ion-spinner[aria-label]'); + const isCompleted = () => !isLoading() && !infiniteLoading.querySelector('ion-button'); + const hasMoved = () => infiniteLoading.offsetTop !== initialOffset; + + if (isCompleted()) { + return 'ERROR: All items are already loaded.'; + } + + infiniteLoading.scrollIntoView({ behavior: 'smooth' }); + + // Wait 100ms + await new Promise(resolve => setTimeout(resolve, 100)); + + if (isLoading() || isCompleted() || hasMoved()) { + return 'OK'; + } + + infiniteLoading.querySelector('ion-button')?.click(); + + // Wait 100ms + await new Promise(resolve => setTimeout(resolve, 100)); + + return (isLoading() || isCompleted() || hasMoved()) ? 'OK' : 'ERROR: Couldn\'t load more items.'; + } catch (error) { + return 'ERROR: ' + error.message; + } + } + + /** + * Check whether an item is selected or not. + * + * @param locator Element locator. + * @return YES or NO if successful, or ERROR: followed by message + */ + static isSelected(locator: TestBehatElementLocator): string { + this.log('Action - Is Selected', locator); + + try { + const element = TestsBehatDomUtils.findElementBasedOnText(locator); + + return TestsBehatDomUtils.isElementSelected(element, document.body) ? 'YES' : 'NO'; + } catch (error) { + return 'ERROR: ' + error.message; + } + } + + /** + * Function to press arbitrary item based on its text or Aria label. + * + * @param locator Element locator. + * @return OK if successful, or ERROR: followed by message + */ + static press(locator: TestBehatElementLocator): string { + this.log('Action - Press', locator); + + try { + const found = TestsBehatDomUtils.findElementBasedOnText(locator); + + if (!found) { + return 'ERROR: No element matches locator to press.'; + } + + TestsBehatDomUtils.pressElement(found); + + return 'OK'; + } catch (error) { + return 'ERROR: ' + error.message; + } + } + + /** + * Gets the currently displayed page header. + * + * @return OK: followed by header text if successful, or ERROR: followed by message. + */ + static getHeader(): string { + this.log('Action - Get header'); + + let titles = Array.from(document.querySelectorAll('.ion-page:not(.ion-page-hidden) > ion-header h1')); + titles = titles.filter((title) => TestsBehatDomUtils.isElementVisible(title, document.body)); + + if (titles.length > 1) { + return 'ERROR: Too many possible titles.'; + } else if (!titles.length) { + return 'ERROR: No title found.'; + } else { + const title = titles[0].innerText.trim(); + + return 'OK:' + title; + } + } + + /** + * Sets the text of a field to the specified value. + * + * This currently matches fields only based on the placeholder attribute. + * + * @param field Field name + * @param value New value + * @return OK or ERROR: followed by message + */ + static setField(field: string, value: string): string { + this.log('Action - Set field ' + field + ' to: ' + value); + + const found: HTMLElement | HTMLInputElement | HTMLTextAreaElement =TestsBehatDomUtils.findElementBasedOnText( + { text: field, selector: 'input, textarea, [contenteditable="true"]' }, + ); + + if (!found) { + return 'ERROR: No element matches field to set.'; + } + + // Functions to get/set value depending on field type. + let setValue = (text: string) => { + found.innerHTML = text; + }; + let getValue = () => found.innerHTML; + + if (found instanceof HTMLInputElement || found instanceof HTMLTextAreaElement) { + setValue = (text: string) => { + found.value = text; + }; + getValue = () => found.value; + } + + // Pretend we have cut and pasted the new text. + let event: InputEvent; + if (getValue() !== '') { + event = new InputEvent('input', { + bubbles: true, + view: window, + cancelable: true, + inputType: 'deleteByCut', + }); + + setTimeout(() => { + setValue(''); + found.dispatchEvent(event); + }, 0); + } + + if (value !== '') { + event = new InputEvent('input', { + bubbles: true, + view: window, + cancelable: true, + inputType: 'insertFromPaste', + data: value, + }); + + setTimeout(() => { + setValue(value); + found.dispatchEvent(event); + }, 0); + } + + return 'OK'; + } + + /** + * Get an Angular component instance. + * + * @param selector Element selector + * @param className Constructor class name + * @return Component instance + */ + static getAngularInstance(selector: string, className: string): unknown { + this.log('Action - Get Angular instance ' + selector + ', ' + className); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const activeElement = Array.from(document.querySelectorAll(`.ion-page:not(.ion-page-hidden) ${selector}`)).pop(); + + if (!activeElement || !activeElement.__ngContext__) { + return null; + } + + return activeElement.__ngContext__.find(node => node?.constructor?.name === className); + } + + /** + * Logs information from this Behat runtime JavaScript, including the time and the 'BEHAT' + * keyword so we can easily filter for it if needed. + */ + static log(...args: unknown[]): void { + const now = new Date(); + const nowFormatted = String(now.getHours()).padStart(2, '0') + ':' + + String(now.getMinutes()).padStart(2, '0') + ':' + + String(now.getSeconds()).padStart(2, '0') + '.' + + String(now.getMilliseconds()).padStart(2, '0'); + + console.log('BEHAT: ' + nowFormatted, ...args); // eslint-disable-line no-console + } + +} + +export type BehatTestsWindow = Window & { + M?: { // eslint-disable-line @typescript-eslint/naming-convention + util?: { + pending_js?: string[]; // eslint-disable-line @typescript-eslint/naming-convention + }; + }; + behatInit?: () => void; + behat?: unknown; +}; + +export type TestBehatElementLocator = { + text: string; + within?: TestBehatElementLocator; + near?: TestBehatElementLocator; + selector?: string; +}; From 92d4a6a16b1392e603f882408b81636a2d65137f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 9 May 2022 10:02:11 +0200 Subject: [PATCH 211/220] MOBILE-4061 behat: Handle custom url async function --- .../tests/behat/behat_app.php | 14 ++++++++++-- src/testing/services/behat-runtime.ts | 22 +++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/local-moodleappbehat/tests/behat/behat_app.php b/local-moodleappbehat/tests/behat/behat_app.php index e17c9e1fd..2d59da7ec 100644 --- a/local-moodleappbehat/tests/behat/behat_app.php +++ b/local-moodleappbehat/tests/behat/behat_app.php @@ -731,9 +731,10 @@ class behat_app extends behat_base { throw new DriverException('Invalid custom link title - ' . $title); } - $url = "moodlemobile://link=" . urlencode($pageurl); + $urlscheme = $this->get_mobile_url_scheme(); + $url = "$urlscheme://link=" . urlencode($pageurl); - $this->evaluate_script("return window.urlSchemes.handleCustomURL('$url')"); + $this->evaluate_async_script("return window.behat.handleCustomURL('$url')"); $this->wait_for_pending_js(); } @@ -1180,4 +1181,13 @@ class behat_app extends behat_base { return $result; } + /** + * Returns the current mobile url scheme of the site. + */ + private function get_mobile_url_scheme() { + $mobilesettings = get_config('tool_mobile'); + + return !empty($mobilesettings->forcedurlscheme) ? $mobilesettings->forcedurlscheme : 'moodlemobile'; + } + } diff --git a/src/testing/services/behat-runtime.ts b/src/testing/services/behat-runtime.ts index a13bb61a1..10d573b74 100644 --- a/src/testing/services/behat-runtime.ts +++ b/src/testing/services/behat-runtime.ts @@ -14,6 +14,7 @@ import { TestsBehatDomUtils } from './behat-dom'; import { TestsBehatBlocking } from './behat-blocking'; +import { CoreCustomURLSchemes } from '@services/urlschemes'; /** * Behat runtime servive with public API. @@ -35,14 +36,31 @@ export class TestsBehatRuntime { pressStandard: TestsBehatRuntime.pressStandard, scrollTo: TestsBehatRuntime.scrollTo, setField: TestsBehatRuntime.setField, + handleCustomURL: TestsBehatRuntime.handleCustomURL, }; } + /** + * Handles a custom URL. + * + * @param url Url to open. + * @return OK if successful, or ERROR: followed by message. + */ + static async handleCustomURL(url: string): Promise { + try { + await CoreCustomURLSchemes.handleCustomURL(url); + + return 'OK'; + } catch (error) { + return 'ERROR: ' + error.message; + } + } + /** * Function to find and click an app standard button. * - * @param button Type of button to press - * @return OK if successful, or ERROR: followed by message + * @param button Type of button to press. + * @return OK if successful, or ERROR: followed by message. */ static pressStandard(button: string): string { this.log('Action - Click standard button: ' + button); From 97862f40f577fefec0c63ec8969b422e2ed3bb92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 9 May 2022 10:40:57 +0200 Subject: [PATCH 212/220] MOBILE-4061 behat: Native handle of skip on boarding --- .../tests/behat/behat_app.php | 30 +++++-------------- .../login/tests/behat/basic_usage.feature | 8 +++++ src/testing/services/behat-runtime.ts | 29 +++++++++++++++++- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/local-moodleappbehat/tests/behat/behat_app.php b/local-moodleappbehat/tests/behat/behat_app.php index 2d59da7ec..098e1a06f 100644 --- a/local-moodleappbehat/tests/behat/behat_app.php +++ b/local-moodleappbehat/tests/behat/behat_app.php @@ -470,7 +470,6 @@ class behat_app extends behat_base { */ protected function prepare_browser(array $options = []) { $restart = $options['restart'] ?? true; - $skiponboarding = $options['skiponboarding'] ?? true; if ($restart) { if ($this->apprunning) { @@ -509,32 +508,23 @@ class behat_app extends behat_base { try { // Init Behat JavaScript runtime. - $this->execute_script('window.behatInit();'); + + $initOptions = new StdClass(); + $initOptions->skipOnBoarding = $options['skiponboarding'] ?? true; + $initOptions->configOverrides = $this->appconfig; + + $this->execute_script('window.behatInit(' . json_encode($initOptions) . ');'); } catch (Exception $error) { throw new DriverException('Moodle app not running or not running on Automated mode.'); } - if ($restart) { // Assert initial page. - $this->spin(function($context) use ($skiponboarding) { + $this->spin(function($context) { $page = $context->getSession()->getPage(); $element = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); if ($element) { - if (!$skiponboarding) { - return true; - } - - // Wait for the onboarding modal to open, if any. - $this->wait_for_pending_js(); - - $element = $page->find('xpath', '//core-login-site-onboarding'); - - if ($element) { - $this->i_press_in_the_app('"Skip"'); - } - // Login screen found. return true; } @@ -548,12 +538,6 @@ class behat_app extends behat_base { }, false, 60); } - // Prepare testing config. - $configoverrides = json_encode($this->appconfig); - - $this->evaluate_script("document.cookie='MoodleAppConfig=$configoverrides'"); - $this->evaluate_script("configProvider.patchEnvironment($configoverrides)"); - // Continue only after JS finishes. $this->wait_for_pending_js(); } diff --git a/src/core/features/login/tests/behat/basic_usage.feature b/src/core/features/login/tests/behat/basic_usage.feature index b94698e0b..4230ddfa9 100755 --- a/src/core/features/login/tests/behat/basic_usage.feature +++ b/src/core/features/login/tests/behat/basic_usage.feature @@ -17,6 +17,14 @@ Feature: Test basic usage of login in app | student2 | C1 | student | | teacher1 | C1 | editingteacher | + Scenario: Skip on boarding + When I launch the app runtime + Then I should find "Welcome to the Moodle App!" in the app + + When I press "Skip" in the app + Then I should not find "Skip" in the app + And I should find "Connect to Moodle" in the app + Scenario: Add a new account in the app & Site name in displayed when adding a new account When I enter the app And I press the back button in the app diff --git a/src/testing/services/behat-runtime.ts b/src/testing/services/behat-runtime.ts index 10d573b74..25fb88f35 100644 --- a/src/testing/services/behat-runtime.ts +++ b/src/testing/services/behat-runtime.ts @@ -15,13 +15,21 @@ import { TestsBehatDomUtils } from './behat-dom'; import { TestsBehatBlocking } from './behat-blocking'; import { CoreCustomURLSchemes } from '@services/urlschemes'; +import { CoreLoginHelperProvider } from '@features/login/services/login-helper'; +import { CoreConfig } from '@services/config'; +import { EnvironmentConfig } from '@/types/config'; /** * Behat runtime servive with public API. */ export class TestsBehatRuntime { - static init(): void { + /** + * Init behat functions and set options like skipping onboarding. + * + * @param options Options to set on the app. + */ + static init(options?: TestsBehatInitOptions): void { TestsBehatBlocking.init(); (window as BehatTestsWindow).behat = { @@ -38,6 +46,20 @@ export class TestsBehatRuntime { setField: TestsBehatRuntime.setField, handleCustomURL: TestsBehatRuntime.handleCustomURL, }; + + if (!options) { + return; + } + + if (options.skipOnBoarding === true) { + CoreConfig.set(CoreLoginHelperProvider.ONBOARDING_DONE, 1); + } + + if (options.configOverrides) { + // Set the cookie so it's maintained between reloads. + document.cookie = 'MoodleAppConfig=' + JSON.stringify(options.configOverrides); + CoreConfig.patchEnvironment(options.configOverrides); + } } /** @@ -407,3 +429,8 @@ export type TestBehatElementLocator = { near?: TestBehatElementLocator; selector?: string; }; + +export type TestsBehatInitOptions = { + skipOnBoarding?: boolean; + configOverrides?: Partial; +}; From a94da4d80443d336dea7828530b97b14b571ab9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 12 May 2022 15:27:52 +0200 Subject: [PATCH 213/220] MOBILE-4061 behat: Generate custom URL to quickly bypass steps on app --- .../tests/behat/behat_app.php | 146 +++++++++++++++--- .../messages/tests/behat/basic_usage.feature | 108 ++++++------- .../messages/tests/behat/navigation.feature | 5 +- .../messages/tests/behat/settings.feature | 5 +- .../tests/behat/basic_usage-310.feature | 8 +- .../assign/tests/behat/basic_usage.feature | 30 ++-- .../mod/assign/tests/behat/navigation.feature | 4 +- .../mod/chat/tests/behat/basic_usage.feature | 14 +- .../mod/chat/tests/behat/navigation.feature | 4 +- .../tests/behat/basic_usage-311.feature | 8 +- .../choice/tests/behat/basic_usage.feature | 28 ++-- .../mod/forum/tests/behat/basic_usage.feature | 58 +++---- .../mod/forum/tests/behat/navigation.feature | 4 +- .../glossary/tests/behat/navigation.feature | 4 +- .../mod/quiz/tests/behat/basic_usage.feature | 16 +- .../quiz/tests/behat/quiz_navigation.feature | 6 +- .../tests/behat/basic_usage-311.feature | 14 +- .../course/tests/behat/basic_usage.feature | 22 ++- .../tests/behat/course_completion-310.feature | 4 +- .../tests/behat/course_completion.feature | 4 +- .../course/tests/behat/courselist-311.feature | 15 +- .../course/tests/behat/courselist.feature | 15 +- .../tests/behat/basic_usage-310.feature | 14 +- .../tests/behat/basic_usage-311.feature | 24 ++- .../courses/tests/behat/basic_usage.feature | 29 ++-- .../login/tests/behat/basic_usage.feature | 5 +- .../mainmenu/tests/behat/mainmenu-311.feature | 10 +- .../mainmenu/tests/behat/mainmenu.feature | 15 +- .../tests/behat/settings_navigation.feature | 6 +- .../siteplugins/tests/behat/plugins.feature | 5 +- .../usertours/tests/behat/usertours.feature | 5 +- src/core/services/sites.ts | 4 +- src/tests/behat/navigation_activities.feature | 4 +- src/tests/behat/navigation_deeplinks.feature | 10 +- .../behat/navigation_externallinks.feature | 4 +- src/tests/behat/navigation_gestures.feature | 8 +- src/tests/behat/navigation_splitview.feature | 6 +- src/tests/behat/performance.feature | 8 +- 38 files changed, 356 insertions(+), 323 deletions(-) diff --git a/local-moodleappbehat/tests/behat/behat_app.php b/local-moodleappbehat/tests/behat/behat_app.php index 098e1a06f..2ff4b7890 100644 --- a/local-moodleappbehat/tests/behat/behat_app.php +++ b/local-moodleappbehat/tests/behat/behat_app.php @@ -125,6 +125,20 @@ class behat_app extends behat_base { $this->enter_site(); } + /** + * Opens the Moodle app in the browser logged in as a user. + * + * @Given /^I enter(ed)? the app as "(.+)"$/ + * @throws DriverException Issue with configuration or feature file + * @throws dml_exception Problem with Moodle setup + * @throws ExpectationException Problem with resizing window + */ + public function i_entered_the_app_as(bool $unused, string $username) { + $this->i_launch_the_app(); + + $this->open_moodleapp_custom_login_url($username); + } + /** * Opens the Moodle app in the browser. * @@ -587,33 +601,27 @@ class behat_app extends behat_base { /** * User enters a course in the app. * - * @Given /^I enter the course "(.+?)"(?: as "(.+)")? in the app$/ + * @Given /^I enter(ed)? the course "(.+?)"(?: as "(.+)")? in the app$/ * @param string $coursename Course name * @throws DriverException If the button push doesn't work */ - public function i_enter_the_course_in_the_app(string $coursename, ?string $username = null) { - if (!is_null($username)) { - $this->i_enter_the_app(); - $this->login($username); + public function i_enter_the_course_in_the_app(bool $unused, string $coursename, ?string $username = null) { + global $DB; + + $courseid = $DB->get_field('course', 'id', [ 'fullname' => $coursename]); + if (!$courseid) { + throw new DriverException("Course '$coursename' not found"); } - $mycoursesfound = $this->evaluate_script("return window.behat.find({ text: 'My courses', selector: 'ion-tab-button'});"); + if ($username) { + $this->i_launch_the_app(); - if ($mycoursesfound !== 'OK') { - // My courses not present enter from Dashboard. - $this->i_press_in_the_app('"Home" "ion-tab-button"'); - $this->i_press_in_the_app('"Dashboard"'); - $this->i_press_in_the_app('"'.$coursename.'" near "Course overview"'); - - $this->wait_for_pending_js(); - - return; + $this->open_moodleapp_custom_login_url($username, "/course/view.php?id=$courseid", '//page-core-course-index'); + } else { + $this->open_moodleapp_custom_url("/course/view.php?id=$courseid", '//page-core-course-index'); } - $this->i_press_in_the_app('"My courses" "ion-tab-button"'); - $this->i_press_in_the_app('"'.$coursename.'"'); - $this->wait_for_pending_js(); } /** @@ -701,25 +709,21 @@ class behat_app extends behat_base { switch ($title) { case 'discussion': $discussion = $DB->get_record('forum_discussions', ['name' => $data->discussion]); - $pageurl = "{$CFG->behat_wwwroot}/mod/forum/discuss.php?d={$discussion->id}"; + $pageurl = "/mod/forum/discuss.php?d={$discussion->id}"; break; case 'forum': $forumdata = $DB->get_record('forum', ['name' => $data->forum]); $cm = get_coursemodule_from_instance('forum', $forumdata->id); - $pageurl = "{$CFG->behat_wwwroot}/mod/forum/view.php?id={$cm->id}"; + $pageurl = "/mod/forum/view.php?id={$cm->id}"; break; default: throw new DriverException('Invalid custom link title - ' . $title); } - $urlscheme = $this->get_mobile_url_scheme(); - $url = "$urlscheme://link=" . urlencode($pageurl); - - $this->evaluate_async_script("return window.behat.handleCustomURL('$url')"); - $this->wait_for_pending_js(); + $this->open_moodleapp_custom_url($pageurl); } /** @@ -1165,6 +1169,98 @@ class behat_app extends behat_base { return $result; } + /** + * Opens a custom URL for automatic login and redirect from the mobile app (and waits to finish.) + * + * @param string $username Of the user that needs to be logged in. + * @param string $path To redirect the user. + * @param string $successXPath If a path is declared, the XPath of the element to lookat after redirect. + */ + private function open_moodleapp_custom_login_url($username, $path = '', string $successXPath = '') { + global $CFG, $DB; + + require_once($CFG->libdir.'/externallib.php'); + require_once($CFG->libdir.'/moodlelib.php'); + + // Ensure the user exists. + $userid = $DB->get_field('user', 'id', [ 'username' => $username ]); + if (!$userid) { + throw new DriverException("User '$username' not found"); + } + + // Get or create the user token. + $service = $DB->get_record('external_services', ['shortname' => 'moodle_mobile_app']); + + $token_params = [ + 'userid' => $userid, + 'externalserviceid' => $service->id, + ]; + $usertoken = $DB->get_record('external_tokens', $token_params); + if (!$usertoken) { + $context = context_system::instance(); + $token = external_generate_token(EXTERNAL_TOKEN_PERMANENT, $service, $userid, $context); + $token_params['token'] = $token; + $privatetoken = $DB->get_field('external_tokens', 'privatetoken', $token_params); + } else { + $token = $usertoken->token; + $privatetoken = $usertoken->privatetoken; + } + + // Generate custom URL. + $parsed_url = parse_url($CFG->behat_wwwroot); + $domain = $parsed_url['host']; + $url = $this->get_mobile_url_scheme() . "://$username@$domain?token=$token&privatetoken=$privatetoken"; + + if (!empty($path)) { + $url .= '&redirect='.urlencode($CFG->behat_wwwroot.$path); + } else { + $successXPath = '//page-core-mainmenu'; + } + + $this->handle_url_and_wait_page_to_load($url, $successXPath); + } + + /** + * Opens a custom URL on the mobile app (and waits to finish.) + * + * @param string $path To navigate. + * @param string $successXPath The XPath of the element to lookat after navigation. + */ + private function open_moodleapp_custom_url(string $path, string $successXPath = '') { + global $CFG; + + $urlscheme = $this->get_mobile_url_scheme(); + $url = "$urlscheme://link=" . urlencode($CFG->behat_wwwroot.$path); + + $this->handle_url_and_wait_page_to_load($url); + } + + /** + * Handles the custom URL on the mobile app (and waits to finish.) + * + * @param string $customurl To navigate. + * @param string $successXPath The XPath of the element to lookat after navigation. + */ + private function handle_url_and_wait_page_to_load(string $customurl, string $successXPath = '') { + // Instead of using evaluate_async_script, we wait for the path to load. + $this->evaluate_script("return window.behat.handleCustomURL('$customurl')"); + + if (!empty($successXPath)) { + // Wait until the page appears. + $this->spin( + function($context, $args) use ($successXPath) { + $found = $context->getSession()->getPage()->find('xpath', $successXPath); + if ($found) { + return true; + } + throw new DriverException('Moodle App custom URL page not loaded'); + }, false, 30); + } + + // Wait for JS to finish as well. + $this->wait_for_pending_js(); + } + /** * Returns the current mobile url scheme of the site. */ diff --git a/src/addons/messages/tests/behat/basic_usage.feature b/src/addons/messages/tests/behat/basic_usage.feature index 638877888..9ef3ed120 100755 --- a/src/addons/messages/tests/behat/basic_usage.feature +++ b/src/addons/messages/tests/behat/basic_usage.feature @@ -20,9 +20,8 @@ Feature: Test basic usage of messages in app | student2 | C1 | student | Scenario: View recent conversations and contacts - When I enter the app - And I log in as "teacher1" - And I press "Messages" in the app + Given I entered the app as "teacher1" + When I press "Messages" in the app And I press "Contacts" in the app Then I should find "No contacts" in the app @@ -37,9 +36,8 @@ Feature: Test basic usage of messages in app And I press "Add" near "Are you sure you want to add Student1 student1 to your contacts?" in the app Then I should find "Contact request sent" in the app - When I enter the app - And I log in as "student1" - And I press "Messages" in the app + Given I entered the app as "student1" + When I press "Messages" in the app And I press "Contacts" in the app And I press "Requests" in the app And I press "Teacher teacher" in the app @@ -57,9 +55,8 @@ Feature: Test basic usage of messages in app And I should find "heeey student" in the app Scenario: Search users - When I enter the app - And I log in as "student1" - And I press "Messages" in the app + Given I entered the app as "student1" + When I press "Messages" in the app And I press "Search people and messages" in the app And I set the field "Search" to "student2" in the app And I press "Search" "button" in the app @@ -70,9 +67,8 @@ Feature: Test basic usage of messages in app Then I should find "Teacher teacher" in the app Scenario: Send/receive messages in existing conversations - When I enter the app - And I log in as "teacher1" - And I press "Messages" in the app + Given I entered the app as "teacher1" + When I press "Messages" in the app And I press "Contacts" in the app And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app @@ -82,9 +78,8 @@ Feature: Test basic usage of messages in app And I press "Send" in the app Then I should find "heeey student" in the app - When I enter the app - And I log in as "student1" - And I press "Messages" in the app + Given I entered the app as "student1" + When I press "Messages" in the app And I press "Contacts" in the app And I press "Search people and messages" in the app And I set the field "Search" to "teacher" in the app @@ -96,9 +91,8 @@ Feature: Test basic usage of messages in app And I press "Send" in the app Then I should find "hi" in the app - When I enter the app - And I log in as "teacher1" - And I press "Messages" in the app + Given I entered the app as "teacher1" + When I press "Messages" in the app And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app And I press "Search" "button" in the app @@ -114,9 +108,8 @@ Feature: Test basic usage of messages in app # TODO Fix this test in all Moodle versions Scenario: User profile: send message, add/remove contact - When I enter the app - And I log in as "teacher1" - And I press "Messages" in the app + Given I entered the app as "teacher1" + When I press "Messages" in the app And I press "Contacts" in the app And I press "Search people and messages" in the app And I set the field "Search" to "student" in the app @@ -131,9 +124,8 @@ Feature: Test basic usage of messages in app And I press "Add" in the app Then I should find "Contact request sent" in the app - When I enter the app - And I log in as "student1" - And I press "Messages" in the app + Given I entered the app as "student1" + When I press "Messages" in the app And I press "Contacts" in the app And I press "Requests" in the app And I press "Teacher teacher" in the app @@ -165,9 +157,8 @@ Feature: Test basic usage of messages in app And I should not find "hi" in the app Scenario: Send message offline - When I enter the app - And I log in as "teacher1" - And I press "Messages" in the app + Given I entered the app as "teacher1" + When I press "Messages" in the app And I press "Contacts" in the app And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app @@ -188,17 +179,15 @@ Feature: Test basic usage of messages in app Then I should find "heeey student" in the app And I should find "byee" in the app - When I enter the app - And I log in as "student1" - And I press "Messages" in the app + Given I entered the app as "student1" + When I press "Messages" in the app And I press "Teacher teacher" in the app Then I should find "heeey student" in the app And I should find "byee" in the app Scenario: Auto-sync messages - When I enter the app - And I log in as "teacher1" - And I press "Messages" in the app + Given I entered the app as "teacher1" + When I press "Messages" in the app And I press "Contacts" in the app And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app @@ -213,17 +202,15 @@ Feature: Test basic usage of messages in app When I switch offline mode to "false" And I run cron tasks in the app - And I enter the app - And I log in as "student1" + And I enter the app as "student1" And I press "Messages" in the app And I press "Teacher teacher" in the app Then I should find "heeey student" in the app And I should find "byee" in the app Scenario: Search for messages - When I enter the app - And I log in as "teacher1" - And I press "Messages" in the app + Given I entered the app as "teacher1" + When I press "Messages" in the app And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app And I press "Search" "button" in the app @@ -236,9 +223,8 @@ Feature: Test basic usage of messages in app And I press "Send" in the app Then I should find "search this message" in the app - When I enter the app - And I log in as "student1" - And I press "Messages" in the app + Given I entered the app as "student1" + When I press "Messages" in the app And I press "Search people and messages" in the app And I set the field "Search" to "search this message" in the app And I press "Search" "button" in the app @@ -250,9 +236,8 @@ Feature: Test basic usage of messages in app And I should find "search this message" in the app Scenario: Star/Unstar - When I enter the app - And I log in as "teacher1" - And I press "Messages" in the app + Given I entered the app as "teacher1" + When I press "Messages" in the app And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app And I press "Search" "button" in the app @@ -261,9 +246,8 @@ Feature: Test basic usage of messages in app And I press "Send" in the app Then I should find "star message" in the app - When I enter the app - And I log in as "student2" - And I press "Messages" in the app + Given I entered the app as "student2" + When I press "Messages" in the app And I press "Search people and messages" in the app And I set the field "Search" to "student1" in the app And I press "Search" "button" in the app @@ -272,9 +256,8 @@ Feature: Test basic usage of messages in app And I press "Send" in the app Then I should find "test message student2" in the app - When I enter the app - And I log in as "student1" - And I press "Messages" in the app + Given I entered the app as "student1" + When I press "Messages" in the app Then I should find "Private (2)" in the app And I should find "Starred (1)" in the app @@ -290,8 +273,8 @@ Feature: Test basic usage of messages in app And I should find "Student1 student1" in the app Scenario: User blocking feature - When I enter the course "Course 1" as "student2" in the app - And I press "Participants" in the app + Given I entered the course "Course 1" as "student2" in the app + When I press "Participants" in the app And I press "Student1 student1" in the app And I press "Message" in the app And I press "Display options" in the app @@ -299,14 +282,14 @@ Feature: Test basic usage of messages in app And I press "Block user" near "Are you sure you want to block Student1 student1?" in the app Then I should find "You have blocked this user" in the app - When I enter the course "Course 1" as "student1" in the app - And I press "Participants" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app Then I should find "You are unable to message this user" in the app - When I enter the course "Course 1" as "student2" in the app - And I press "Participants" in the app + Given I entered the course "Course 1" as "student2" in the app + When I press "Participants" in the app And I press "Student1 student1" in the app And I press "Message" in the app And I press "Display options" in the app @@ -317,8 +300,8 @@ Feature: Test basic usage of messages in app And I press "Unblock user" near "Are you sure you want to unblock Student1 student1?" in the app Then I should not find "You have blocked this user" in the app - When I enter the course "Course 1" as "student1" in the app - And I press "Participants" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app And I set the field "New message" to "test message" in the app @@ -327,8 +310,8 @@ Feature: Test basic usage of messages in app But I should not find "You are unable to message this user" in the app Scenario: Mute Unmute conversations - When I enter the course "Course 1" as "student1" in the app - And I press "Participants" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Participants" in the app And I press "Student2 student2" in the app And I press "Message" in the app And I set the field "New message" to "test message" in the app @@ -354,9 +337,8 @@ Feature: Test basic usage of messages in app And I should find "Muted conversation" in the app Scenario: Self conversations - When I enter the app - And I log in as "student1" - And I press "Messages" in the app + Given I entered the app as "student1" + When I press "Messages" in the app Then I should find "Starred (1)" in the app When I press "Student1 student1" in the app diff --git a/src/addons/messages/tests/behat/navigation.feature b/src/addons/messages/tests/behat/navigation.feature index 5be92c2ca..2fd1e3685 100644 --- a/src/addons/messages/tests/behat/navigation.feature +++ b/src/addons/messages/tests/behat/navigation.feature @@ -15,9 +15,8 @@ Feature: Test messages navigation in the app | student | C1 | student | Scenario: Avoid recursive links to profile - When I enter the app - And I log in as "teacher" - And I press "Messages" in the app + Given I entered the app as "teacher" + When I press "Messages" in the app And I press "Contacts" in the app And I press "Search people and messages" in the app And I set the field "Search" to "student" in the app diff --git a/src/addons/messages/tests/behat/settings.feature b/src/addons/messages/tests/behat/settings.feature index 227ddfc1a..ca2499b48 100644 --- a/src/addons/messages/tests/behat/settings.feature +++ b/src/addons/messages/tests/behat/settings.feature @@ -7,9 +7,8 @@ Feature: Test messages settings | student1 | Scenario: Modify settings - When I enter the app - And I log in as "student1" - And I press "Messages" in the app + Given I entered the app as "student1" + When I press "Messages" in the app And I press "Message preferences" in the app And I select "My contacts only" in the app Then "My contacts only" should be selected in the app diff --git a/src/addons/mod/assign/tests/behat/basic_usage-310.feature b/src/addons/mod/assign/tests/behat/basic_usage-310.feature index 2141af2b9..cdd88aeef 100755 --- a/src/addons/mod/assign/tests/behat/basic_usage-310.feature +++ b/src/addons/mod/assign/tests/behat/basic_usage-310.feature @@ -21,8 +21,8 @@ Feature: Test basic usage of assignment activity in app Scenario: View assign description, due date & View list of student submissions (as teacher) & View own submission or student submission # Create, edit and submit as a student - When I enter the course "Course 1" as "student1" in the app - And I press "assignment1" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "assignment1" in the app Then the header should be "assignment1" in the app And I should find "Test assignment description1" in the app And I should find "Due date" in the app @@ -47,8 +47,8 @@ Feature: Test basic usage of assignment activity in app And I should find "Submission test edited" in the app # View as a teacher - When I enter the course "Course 1" as "teacher1" in the app - And I press "assignment1" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "assignment1" in the app Then the header should be "assignment1" in the app When I press "Submitted" in the app diff --git a/src/addons/mod/assign/tests/behat/basic_usage.feature b/src/addons/mod/assign/tests/behat/basic_usage.feature index f8521f987..9e26048be 100755 --- a/src/addons/mod/assign/tests/behat/basic_usage.feature +++ b/src/addons/mod/assign/tests/behat/basic_usage.feature @@ -22,8 +22,8 @@ Feature: Test basic usage of assignment activity in app @lms_from3.11 Scenario: View assign description, due date & View list of student submissions (as teacher) & View own submission or student submission # Create, edit and submit as a student - When I enter the course "Course 1" as "student1" in the app - And I press "assignment1" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "assignment1" in the app Then the header should be "assignment1" in the app And I should find "Test assignment description1" in the app And I should find "Due:" in the app @@ -48,8 +48,8 @@ Feature: Test basic usage of assignment activity in app And I should find "Submission test edited" in the app # View as a teacher - When I enter the course "Course 1" as "teacher1" in the app - And I press "assignment1" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "assignment1" in the app Then the header should be "assignment1" in the app When I press "Submitted" in the app @@ -62,7 +62,7 @@ Feature: Test basic usage of assignment activity in app Scenario: Edit/Add submission (online text) & Add new attempt from previous submission & Submit for grading # Submit first attempt as a student - Given I enter the course "Course 1" as "student1" in the app + Given I entered the course "Course 1" as "student1" in the app And I press "assignment1" in the app And I press "Add submission" in the app And I set the field "Online text submissions" to "Submission test 1st attempt" in the app @@ -71,8 +71,8 @@ Feature: Test basic usage of assignment activity in app And I press "OK" in the app # Allow more attempts as a teacher - When I enter the course "Course 1" as "teacher1" in the app - And I press "assignment1" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "assignment1" in the app And I press "Participants" in the app And I press "Student student" near "assignment1" in the app And I press "Grade" in the app @@ -82,8 +82,8 @@ Feature: Test basic usage of assignment activity in app And I should find "Not graded" in the app # Submit second attempt as a student - When I enter the course "Course 1" as "student1" in the app - And I press "assignment1" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "assignment1" in the app Then I should find "Reopened" in the app And I should find "2 out of Unlimited" in the app And I should find "Add a new attempt based on previous submission" in the app @@ -100,16 +100,16 @@ Feature: Test basic usage of assignment activity in app And I press "OK" in the app # View second attempt as a teacher - When I enter the course "Course 1" as "teacher1" in the app - And I press "assignment1" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "assignment1" in the app And I press "Participants" in the app And I press "Student student" near "assignment1" in the app Then I should find "Online text submissions" in the app And I should find "Submission test 2nd attempt" in the app Scenario: Add submission offline (online text) & Submit for grading offline & Sync submissions - When I enter the course "Course 1" as "student1" in the app - And I press "assignment1" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "assignment1" in the app And I press "Add submission" in the app And I switch offline mode to "true" And I set the field "Online text submissions" to "Submission test" in the app @@ -127,8 +127,8 @@ Feature: Test basic usage of assignment activity in app But I should not find "This Assignment has offline data to be synchronised." in the app Scenario: Edit an offline submission before synchronising it - When I enter the course "Course 1" as "student1" in the app - And I press "assignment1" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "assignment1" in the app And I press "Add submission" in the app And I switch offline mode to "true" And I set the field "Online text submissions" to "Submission test original offline" in the app diff --git a/src/addons/mod/assign/tests/behat/navigation.feature b/src/addons/mod/assign/tests/behat/navigation.feature index 95744dc49..12ee6c291 100644 --- a/src/addons/mod/assign/tests/behat/navigation.feature +++ b/src/addons/mod/assign/tests/behat/navigation.feature @@ -36,7 +36,7 @@ Feature: Test assignments navigation | assignment | student3 | Ipsum | Scenario: Mobile navigation - Given I enter the course "Course 1" as "teacher1" in the app + Given I entered the course "Course 1" as "teacher1" in the app # Initial status When I press "Assignment" in the app @@ -150,7 +150,7 @@ Feature: Test assignments navigation And I should not find "Second Student" in the app Scenario: Tablet navigation - Given I enter the course "Course 1" as "teacher1" in the app + Given I entered the course "Course 1" as "teacher1" in the app And I change viewport size to "1200x640" # Initial status diff --git a/src/addons/mod/chat/tests/behat/basic_usage.feature b/src/addons/mod/chat/tests/behat/basic_usage.feature index ef4f1d2da..d739a2df9 100755 --- a/src/addons/mod/chat/tests/behat/basic_usage.feature +++ b/src/addons/mod/chat/tests/behat/basic_usage.feature @@ -21,8 +21,8 @@ Feature: Test basic usage of chat in app Scenario: Receive and send messages & See connected users, beep and talk to # Send messages as student1 - When I enter the course "Course 1" as "student1" in the app - And I press "Test chat name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test chat name" in the app Then I should find "Enter the chat" in the app And I should find "Past sessions" in the app @@ -37,8 +37,8 @@ Feature: Test basic usage of chat in app And I should find "I am David" in the app # Read messages, view connected users, send beep and reply as student2 - When I enter the course "Course 1" as "student2" in the app - And I press "Test chat name" in the app + Given I entered the course "Course 1" as "student2" in the app + When I press "Test chat name" in the app And I press "Enter the chat" in the app Then I should find "Hi!" in the app And I should find "I am David" in the app @@ -55,7 +55,7 @@ Feature: Test basic usage of chat in app Scenario: Past sessions shown # Send messages as student1 - Given I enter the course "Course 1" as "student1" in the app + Given I entered the course "Course 1" as "student1" in the app And I press "Test chat name" in the app And I press "Enter the chat" in the app And I set the field "New message" to "Hi!" in the app @@ -67,8 +67,8 @@ Feature: Test basic usage of chat in app Then I should find "I am David" in the app # Read messages from past sessions as student2 - When I enter the course "Course 1" as "student2" in the app - And I press "Test chat name" in the app + Given I entered the course "Course 1" as "student2" in the app + When I press "Test chat name" in the app And I press "Past sessions" in the app And I press "Show incomplete sessions" in the app And I press "david student" near "(2)" in the app diff --git a/src/addons/mod/chat/tests/behat/navigation.feature b/src/addons/mod/chat/tests/behat/navigation.feature index eccea87d3..0b757fb3a 100644 --- a/src/addons/mod/chat/tests/behat/navigation.feature +++ b/src/addons/mod/chat/tests/behat/navigation.feature @@ -18,7 +18,7 @@ Feature: Test chat navigation | chat | Test chat name | Test chat | C1 | chat | 0 | # Create sessions # TODO use generator instead - And I enter the course "Course 1" as "student1" in the app + And I entered the course "Course 1" as "student1" in the app And I press "Test chat name" in the app And I press "Enter the chat" in the app And I set the field "New message" to "Test message" in the app @@ -26,7 +26,7 @@ Feature: Test chat navigation Then I should find "Test message" in the app Scenario: Tablet navigation - Given I enter the course "Course 1" as "student2" in the app + Given I entered the course "Course 1" as "student2" in the app And I change viewport size to "1200x640" # Sessions diff --git a/src/addons/mod/choice/tests/behat/basic_usage-311.feature b/src/addons/mod/choice/tests/behat/basic_usage-311.feature index c5c0c90d3..6ce9f1e60 100755 --- a/src/addons/mod/choice/tests/behat/basic_usage-311.feature +++ b/src/addons/mod/choice/tests/behat/basic_usage-311.feature @@ -22,15 +22,15 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | - And I enter the course "Course 1" as "student1" in the app - And I press "Choice name" in the app + And I entered the course "Course 1" as "student1" in the app + Then I press "Choice name" in the app And I select "Option 2" in the app And I press "Save my choice" in the app And I press "OK" in the app # Download answers as teacher - When I enter the course "Course 1" as "teacher1" in the app - And I press "Choice name" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "Choice name" in the app Then I should find "Test choice description" in the app When I press "Information" in the app diff --git a/src/addons/mod/choice/tests/behat/basic_usage.feature b/src/addons/mod/choice/tests/behat/basic_usage.feature index 73690ccc8..8585a6ab4 100755 --- a/src/addons/mod/choice/tests/behat/basic_usage.feature +++ b/src/addons/mod/choice/tests/behat/basic_usage.feature @@ -21,8 +21,8 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - When I enter the course "Course 1" as "student1" in the app - And I press "Test single choice name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test single choice name" in the app And I select "Option 1" in the app And I select "Option 2" in the app And I press "Save my choice" in the app @@ -44,8 +44,8 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | - When I enter the course "Course 1" as "student1" in the app - And I press "Test multi choice name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test multi choice name" in the app And I select "Option 1" in the app And I select "Option 2" in the app And I press "Save my choice" in the app @@ -72,8 +72,8 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - When I enter the course "Course 1" as "student1" in the app - And I press "Test single choice name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test single choice name" in the app And I select "Option 1" in the app And I switch offline mode to "true" And I select "Option 2" in the app @@ -104,8 +104,8 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - When I enter the course "Course 1" as "student1" in the app - And I press "Test single choice name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test single choice name" in the app And I select "Option 1" in the app And I switch offline mode to "true" And I select "Option 2" in the app @@ -131,8 +131,8 @@ Feature: Test basic usage of choice activity in app | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - When I enter the course "Course 1" as "student1" in the app - And I press "Course downloads" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Course downloads" in the app And I press "Download" within "Test single choice name" "ion-item" in the app Then I should find "Downloaded" within "Test single choice name" "ion-item" in the app And I press the back button in the app @@ -171,15 +171,15 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | - And I enter the course "Course 1" as "student1" in the app - And I press "Choice name" in the app + And I entered the course "Course 1" as "student1" in the app + Then I press "Choice name" in the app And I select "Option 2" in the app And I press "Save my choice" in the app And I press "OK" in the app # Download answers as teacher - When I enter the course "Course 1" as "teacher1" in the app - And I press "Choice name" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "Choice name" in the app Then I should find "Test choice description" in the app When I press "Information" in the app diff --git a/src/addons/mod/forum/tests/behat/basic_usage.feature b/src/addons/mod/forum/tests/behat/basic_usage.feature index 88e7aef82..20b075d96 100755 --- a/src/addons/mod/forum/tests/behat/basic_usage.feature +++ b/src/addons/mod/forum/tests/behat/basic_usage.feature @@ -25,8 +25,8 @@ Feature: Test basic usage of forum activity in app | forum | Test forum name | Test forum | C1 | forum | 0 | 1 | 1 | Scenario: Create new discussion - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I press "Add discussion topic" in the app And I set the field "Subject" to "My happy subject" in the app And I set the field "Message" to "An awesome message" in the app @@ -37,8 +37,8 @@ Feature: Test basic usage of forum activity in app Then I should find "An awesome message" in the app Scenario: Reply a post - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app @@ -53,8 +53,8 @@ Feature: Test basic usage of forum activity in app And I should find "ReplyMessage" in the app Scenario: Star and pin discussions (student) - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I press "Add discussion topic" in the app And I set the field "Subject" to "starred subject" in the app And I set the field "Message" to "starred message" in the app @@ -87,8 +87,8 @@ Feature: Test basic usage of forum activity in app Then I should find "normal message" in the app Scenario: Star and pin discussions (teacher) - When I enter the course "Course 1" as "teacher1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "Test forum name" in the app And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test star" in the app And I set the field "Message" to "Auto-test star message" in the app @@ -117,8 +117,8 @@ Feature: Test basic usage of forum activity in app And I should find "Auto-test pin" in the app Scenario: Edit a not sent reply offline - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app @@ -150,8 +150,8 @@ Feature: Test basic usage of forum activity in app And I should not find "This Discussion has offline data to be synchronised" in the app Scenario: Edit a not sent new discussion offline - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I switch offline mode to "true" And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app @@ -173,8 +173,8 @@ Feature: Test basic usage of forum activity in app And I should find "Auto-test message edited" in the app Scenario: Edit a forum post (only online) - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app @@ -200,8 +200,8 @@ Feature: Test basic usage of forum activity in app # TODO Fix this test in all Moodle versions Scenario: Delete a forum post (only online) - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app @@ -233,7 +233,7 @@ Feature: Test basic usage of forum activity in app Then I should not find "Auto-test" in the app Scenario: Add/view ratings - Given I enter the course "Course 1" as "student1" in the app + Given I entered the course "Course 1" as "student1" in the app And I press "Test forum name" in the app And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app @@ -247,8 +247,8 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app Then I should find "test2" "ion-card" in the app - When I enter the course "Course 1" as "teacher1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "Test forum name" in the app And I press "Auto-test" in the app Then I should find "Reply" in the app @@ -274,16 +274,16 @@ Feature: Test basic usage of forum activity in app And I should find "Average of ratings: 0" in the app But I should not find "Average of ratings: -" in the app - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I press "Auto-test" in the app Then I should find "Average of ratings: 1" in the app And I should find "Average of ratings: 0" in the app But I should not find "Average of ratings: -" in the app Scenario: Reply a post offline - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app @@ -312,8 +312,8 @@ Feature: Test basic usage of forum activity in app But I should not find "Not sent" in the app Scenario: New discussion offline & Sync Forum - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I switch offline mode to "true" And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app @@ -335,8 +335,8 @@ Feature: Test basic usage of forum activity in app And I should not find "This Forum has offline data to be synchronised." in the app Scenario: New discussion offline & Auto-sync forum - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I switch offline mode to "true" And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app @@ -358,8 +358,8 @@ Feature: Test basic usage of forum activity in app And I should not find "This Forum has offline data to be synchronised." in the app Scenario: Prefetch - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum name" in the app And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject 1" in the app And I set the field "Message" to "DiscussionMessage 1" in the app diff --git a/src/addons/mod/forum/tests/behat/navigation.feature b/src/addons/mod/forum/tests/behat/navigation.feature index f325f9738..0ecbb040b 100644 --- a/src/addons/mod/forum/tests/behat/navigation.feature +++ b/src/addons/mod/forum/tests/behat/navigation.feature @@ -42,7 +42,7 @@ Feature: Test forum navigation | Discussion 05 | Discussion 05 | Discussion 05 first reply | Scenario: Mobile navigation - Given I enter the course "Course 1" as "student1" in the app + Given I entered the course "Course 1" as "student1" in the app # By last reply When I press "Forum" in the app @@ -139,7 +139,7 @@ Feature: Test forum navigation # Then I should find "Discussion 20 message" in the app Scenario: Tablet navigation - Given I enter the course "Course 1" as "student1" in the app + Given I entered the course "Course 1" as "student1" in the app And I change viewport size to "1200x640" # By last reply diff --git a/src/addons/mod/glossary/tests/behat/navigation.feature b/src/addons/mod/glossary/tests/behat/navigation.feature index c3fac4b74..cd807e65b 100644 --- a/src/addons/mod/glossary/tests/behat/navigation.feature +++ b/src/addons/mod/glossary/tests/behat/navigation.feature @@ -88,7 +88,7 @@ Feature: Test glossary navigation | glossary | Watermelon | Watermelon is a fruit | student2 | Scenario: Mobile navigation - Given I enter the course "Course 1" as "student1" in the app + Given I entered the course "Course 1" as "student1" in the app # Alphabetically When I press "Fruits glossary" in the app @@ -195,7 +195,7 @@ Feature: Test glossary navigation Then I should find "Acerola is a fruit" in the app Scenario: Tablet navigation - Given I enter the course "Course 1" as "student1" in the app + Given I entered the course "Course 1" as "student1" in the app And I change viewport size to "1200x640" # Alphabetically diff --git a/src/addons/mod/quiz/tests/behat/basic_usage.feature b/src/addons/mod/quiz/tests/behat/basic_usage.feature index 4a5e94ba5..c20850298 100755 --- a/src/addons/mod/quiz/tests/behat/basic_usage.feature +++ b/src/addons/mod/quiz/tests/behat/basic_usage.feature @@ -56,8 +56,8 @@ Feature: Attempt a quiz in app | TF9 | 7 | Scenario: View a quiz entry page (attempts, status, etc.) - When I enter the course "Course 1" as "student1" in the app - And I press "Quiz 1" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Quiz 1" in the app And I press "Attempt quiz now" in the app Then I should find "Text of the first question" in the app But I should not find "Text of the second question" in the app @@ -106,8 +106,8 @@ Feature: Attempt a quiz in app And I should find "Question 2" in the app Scenario: Attempt a quiz (all question types) - When I enter the course "Course 1" as "student1" in the app - And I press "Quiz 2" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Quiz 2" in the app And I press "Attempt quiz now" in the app And I press "Four" in the app And I press "Three" in the app @@ -143,8 +143,8 @@ Feature: Attempt a quiz in app And I should find "Not yet graded" in the app Scenario: Submit a quiz & Review a quiz attempt - When I enter the course "Course 1" as "student1" in the app - And I press "Quiz 1" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Quiz 1" in the app And I press "Attempt quiz now" in the app And I press "True" in the app And I press "Next" near "Question 1" in the app @@ -154,8 +154,8 @@ Feature: Attempt a quiz in app And I press "OK" in the app Then I should find "Review" in the app - When I enter the course "Course 1" as "teacher1" in the app - And I press "Quiz 1" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "Quiz 1" in the app And I press "Information" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app diff --git a/src/addons/mod/quiz/tests/behat/quiz_navigation.feature b/src/addons/mod/quiz/tests/behat/quiz_navigation.feature index cf52af5c2..a81c5d0a3 100644 --- a/src/addons/mod/quiz/tests/behat/quiz_navigation.feature +++ b/src/addons/mod/quiz/tests/behat/quiz_navigation.feature @@ -30,10 +30,8 @@ Feature: Attempt a quiz in app | TF2 | 2 | Scenario: Next and previous navigation - Given I enter the app - And I log in as "student1" - When I enter the course "Course 1" in the app - And I press "Quiz 1" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Quiz 1" in the app And I press "Attempt quiz now" in the app Then I should find "Text of the first question" in the app But I should not find "Text of the second question" in the app diff --git a/src/core/features/course/tests/behat/basic_usage-311.feature b/src/core/features/course/tests/behat/basic_usage-311.feature index 2f56e7a6a..9622a2904 100755 --- a/src/core/features/course/tests/behat/basic_usage-311.feature +++ b/src/core/features/course/tests/behat/basic_usage-311.feature @@ -72,7 +72,7 @@ Feature: Test basic usage of one course in app | workshop | Test workshop name | Test workshop | C1 | workshop | 0 | 3 | Scenario: Self enrol - Given I enter the course "Course 1" as "teacher1" in the app + Given I entered the course "Course 1" as "teacher1" in the app And I press "Course summary" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -83,9 +83,8 @@ Feature: Test basic usage of one course in app And I follow "Enrolment methods" And I click on "Enable" "icon" in the "Self enrolment (Student)" "table_row" And I close the browser tab opened by the app - When I enter the app - And I log in as "student2" - And I press "Site home" in the app + Given I entered the app as "student2" + When I press "Site home" in the app And I press "Available courses" in the app And I press "Course 1" in the app And I press "Enrol me" in the app @@ -108,7 +107,7 @@ Feature: Test basic usage of one course in app And I should find "Test workshop name" in the app Scenario: Guest access - Given I enter the course "Course 1" as "teacher1" in the app + Given I entered the course "Course 1" as "teacher1" in the app And I press "Course summary" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -119,9 +118,8 @@ Feature: Test basic usage of one course in app And I follow "Enrolment methods" And I click on "Enable" "icon" in the "Guest access" "table_row" And I close the browser tab opened by the app - When I enter the app - And I log in as "student2" - And I press "Site home" in the app + Given I entered the app as "student2" + When I press "Site home" in the app And I press "Available courses" in the app And I press "Course 1" in the app diff --git a/src/core/features/course/tests/behat/basic_usage.feature b/src/core/features/course/tests/behat/basic_usage.feature index 1674a661c..c849ed61d 100755 --- a/src/core/features/course/tests/behat/basic_usage.feature +++ b/src/core/features/course/tests/behat/basic_usage.feature @@ -72,7 +72,7 @@ Feature: Test basic usage of one course in app | workshop | Test workshop name | Test workshop | C1 | workshop | 0 | 3 | Scenario: View course contents - When I enter the course "Course 1" as "student1" in the app + When I entered the course "Course 1" as "student1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -147,7 +147,7 @@ Feature: Test basic usage of one course in app Then the header should be "Test workshop name" in the app Scenario: View section contents - When I enter the course "Course 1" as "student1" in the app + When I entered the course "Course 1" as "student1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -324,7 +324,7 @@ Feature: Test basic usage of one course in app Then the header should be "Test glossary" in the app Scenario: Navigation between sections using the bottom arrows - When I enter the course "Course 1" as "student1" in the app + When I entered the course "Course 1" as "student1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app @@ -402,7 +402,7 @@ Feature: Test basic usage of one course in app @lms_from4.0 Scenario: Self enrol - Given I enter the course "Course 1" as "teacher1" in the app + Given I entered the course "Course 1" as "teacher1" in the app And I press "Course summary" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -411,9 +411,8 @@ Feature: Test basic usage of one course in app And I select "Enrolment methods" from the "jump" singleselect And I click on "Enable" "icon" in the "Self enrolment (Student)" "table_row" And I close the browser tab opened by the app - When I enter the app - And I log in as "student2" - And I press "Site home" in the app + Given I entered the app as "student2" + When I press "Site home" in the app And I press "Available courses" in the app And I press "Course 1" in the app And I press "Enrol me" in the app @@ -437,7 +436,7 @@ Feature: Test basic usage of one course in app @lms_from4.0 Scenario: Guest access - Given I enter the course "Course 1" as "teacher1" in the app + Given I entered the course "Course 1" as "teacher1" in the app And I press "Course summary" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -446,9 +445,8 @@ Feature: Test basic usage of one course in app And I select "Enrolment methods" from the "jump" singleselect And I click on "Enable" "icon" in the "Guest access" "table_row" And I close the browser tab opened by the app - When I enter the app - And I log in as "student2" - And I press "Site home" in the app + Given I entered the app as "student2" + When I press "Site home" in the app And I press "Available courses" in the app And I press "Course 1" in the app @@ -476,7 +474,7 @@ Feature: Test basic usage of one course in app | blockname | contextlevel | reference | pagetypepattern | defaultregion | configdata | | html | Course | C1 | course-view-* | site-pre | Tzo4OiJzdGRDbGFzcyI6Mjp7czo1OiJ0aXRsZSI7czoxNToiSFRNTCB0aXRsZSB0ZXN0IjtzOjQ6InRleHQiO3M6OToiYm9keSB0ZXN0Ijt9 | | activity_modules | Course | C1 | course-view-* | site-pre | | - When I enter the course "Course 1" as "student1" in the app + And I entered the course "Course 1" as "student1" in the app Then the header should be "Course 1" in the app And I should find "Choice course 1" in the app And I should find "assignment" in the app diff --git a/src/core/features/course/tests/behat/course_completion-310.feature b/src/core/features/course/tests/behat/course_completion-310.feature index 60571703e..566aa109c 100644 --- a/src/core/features/course/tests/behat/course_completion-310.feature +++ b/src/core/features/course/tests/behat/course_completion-310.feature @@ -20,9 +20,9 @@ Feature: Check course completion feature. | activity | name | course | idnumber | completion | completionview | | forum | First forum | C1 | forum1 | 1 | 0 | | forum | Second forum | C1 | forum2 | 1 | 0 | - When I enter the course "Course 1" as "student1" in the app + And I entered the course "Course 1" as "student1" in the app # Set activities as completed. - And I should find "0%" in the app + Then I should find "0%" in the app And I click on "ion-button[title=\"Not completed: First forum. Select to mark as complete.\"]" "css" And I should find "50%" in the app And I click on "ion-button[title=\"Not completed: Second forum. Select to mark as complete.\"]" "css" diff --git a/src/core/features/course/tests/behat/course_completion.feature b/src/core/features/course/tests/behat/course_completion.feature index 06ab51784..32d9a267c 100644 --- a/src/core/features/course/tests/behat/course_completion.feature +++ b/src/core/features/course/tests/behat/course_completion.feature @@ -21,9 +21,9 @@ Feature: Check course completion feature. | activity | name | course | idnumber | completion | completionview | | forum | First forum | C1 | forum1 | 1 | 0 | | forum | Second forum | C1 | forum2 | 1 | 0 | - When I enter the course "Course 1" as "student1" in the app + And I entered the course "Course 1" as "student1" in the app # Set activities as completed. - And I should find "0%" in the app + Then I should find "0%" in the app And I press "Mark First forum as done" in the app And I should find "50%" in the app And I press "Mark Second forum as done" in the app diff --git a/src/core/features/course/tests/behat/courselist-311.feature b/src/core/features/course/tests/behat/courselist-311.feature index 0fd418c6d..4cdc5fe08 100644 --- a/src/core/features/course/tests/behat/courselist-311.feature +++ b/src/core/features/course/tests/behat/courselist-311.feature @@ -20,16 +20,14 @@ Feature: Test course list shown on app start tab | student2 | C2 | student | Scenario: View courses (shortnames not displayed) - When I enter the app - And I log in as "student1" - Then I should find "Course 1" in the app + Given I entered the app as "student1" + When I should find "Course 1" in the app But I should not find "Course 2" in the app But I should not find "C1" in the app But I should not find "C2" in the app - When I enter the app - And I log in as "student2" - Then I should find "Course 1" in the app + Given I entered the app as "student2" + When I should find "Course 1" in the app And I should find "Course 2" in the app But I should not find "C1" in the app But I should not find "C2" in the app @@ -76,9 +74,8 @@ Feature: Test course list shown on app start tab | student2 | Z8 | student | | student2 | Z9 | student | | student2 | Z10 | student | - When I enter the app - And I log in as "student2" - Then I should find "C1" in the app + Given I entered the app as "student2" + When I should find "C1" in the app And I should find "C2" in the app And I should find "C3" in the app And I should find "C4" in the app diff --git a/src/core/features/course/tests/behat/courselist.feature b/src/core/features/course/tests/behat/courselist.feature index 7d1807ac0..f1d99e1dc 100644 --- a/src/core/features/course/tests/behat/courselist.feature +++ b/src/core/features/course/tests/behat/courselist.feature @@ -21,17 +21,15 @@ Feature: Test course list shown on app start tab @lms_from4.0 Scenario: View courses (shortnames not displayed) - When I enter the app - And I log in as "student1" - And I press "My courses" in the app + Given I entered the app as "student1" + When I press "My courses" in the app Then I should find "Course 1" in the app But I should not find "Course 2" in the app But I should not find "C1" in the app But I should not find "C2" in the app - When I enter the app - And I log in as "student2" - And I press "My courses" in the app + Given I entered the app as "student2" + When I press "My courses" in the app Then I should find "Course 1" in the app And I should find "Course 2" in the app But I should not find "C1" in the app @@ -80,9 +78,8 @@ Feature: Test course list shown on app start tab | student2 | Z8 | student | | student2 | Z9 | student | | student2 | Z10 | student | - When I enter the app - And I log in as "student2" - And I press "My courses" in the app + Given I entered the app as "student2" + When I press "My courses" in the app Then I should find "C1" in the app And I should find "C2" in the app And I should find "C3" in the app diff --git a/src/core/features/courses/tests/behat/basic_usage-310.feature b/src/core/features/courses/tests/behat/basic_usage-310.feature index b22b47163..21691d4f3 100755 --- a/src/core/features/courses/tests/behat/basic_usage-310.feature +++ b/src/core/features/courses/tests/behat/basic_usage-310.feature @@ -36,8 +36,8 @@ Feature: Test basic usage of courses in app Scenario: Links to actions in Timeline work for teachers/students # Configure assignment as teacher - Given I enter the course "Course 1" as "teacher1" in the app - And I press "assignment" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "assignment" in the app And I press "Information" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -51,9 +51,8 @@ Feature: Test basic usage of courses in app And I close the browser tab opened by the app # Submit assignment as student - When I enter the app - And I log in as "student1" - Then I press "Open block drawer" in the app + Given I entered the app as "student1" + When I press "Open block drawer" in the app And I press "Add submission" in the app Then the header should be "assignment" in the app And I should find "Test assignment description" in the app @@ -71,9 +70,8 @@ Feature: Test basic usage of courses in app And I should find "Due date" in the app # Grade assignment as teacher - When I enter the app - And I log in as "teacher1" - Then I press "Open block drawer" in the app + Given I entered the app as "teacher1" + When I press "Open block drawer" in the app And I press "Grade" in the app Then the header should be "assignment" in the app And I should find "Test assignment description" in the app diff --git a/src/core/features/courses/tests/behat/basic_usage-311.feature b/src/core/features/courses/tests/behat/basic_usage-311.feature index 1e543d0e3..40f642f36 100755 --- a/src/core/features/courses/tests/behat/basic_usage-311.feature +++ b/src/core/features/courses/tests/behat/basic_usage-311.feature @@ -35,9 +35,8 @@ Feature: Test basic usage of courses in app | assign | C1 | assign1 | assignment | Test assignment description | 1 | Scenario: "Dashboard" tab displayed in >= 3.3 sites - When I enter the app - And I log in as "student1" - Then I should see "Dashboard" + Given I entered the app as "student1" + When I should see "Dashboard" And the header should be "Acceptance test site" in the app And I should find "Course 1" in the app And I should find "Course 2" in the app @@ -53,9 +52,8 @@ Feature: Test basic usage of courses in app And I should find "Course 3" in the app Scenario: See my courses - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app + Given I entered the app as "student1" + When the header should be "Acceptance test site" in the app And I should find "Course 1" in the app And I should find "Course 2" in the app And I should find "Course 3" in the app @@ -82,8 +80,8 @@ Feature: Test basic usage of courses in app @lms_from3.11 Scenario: Links to actions in Timeline work for teachers/students # Configure assignment as teacher - Given I enter the course "Course 1" as "teacher1" in the app - And I press "assignment" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "assignment" in the app And I press "Information" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -97,9 +95,8 @@ Feature: Test basic usage of courses in app And I close the browser tab opened by the app # Submit assignment as student - When I enter the app - And I log in as "student1" - Then I press "Open block drawer" in the app + Given I entered the app as "student1" + When I press "Open block drawer" in the app And I press "Add submission" in the app Then the header should be "assignment" in the app And I should find "Test assignment description" in the app @@ -117,9 +114,8 @@ Feature: Test basic usage of courses in app And I should find "Due:" in the app # Grade assignment as teacher - When I enter the app - And I log in as "teacher1" - Then I press "Open block drawer" in the app + Given I entered the app as "teacher1" + When I press "Open block drawer" in the app And I press "Grade" in the app Then the header should be "assignment" in the app And I should find "Test assignment description" in the app diff --git a/src/core/features/courses/tests/behat/basic_usage.feature b/src/core/features/courses/tests/behat/basic_usage.feature index beab4df32..313e9b063 100755 --- a/src/core/features/courses/tests/behat/basic_usage.feature +++ b/src/core/features/courses/tests/behat/basic_usage.feature @@ -35,9 +35,8 @@ Feature: Test basic usage of courses in app | assign | C1 | assign1 | assignment | Test assignment description | 1 | Scenario: "Dashboard" tab displayed - When I enter the app - And I log in as "student1" - Then I should see "Dashboard" + Given I entered the app as "student1" + When I should see "Dashboard" And the header should be "Acceptance test site" in the app And I should see "Timeline" And I press "Site home" in the app @@ -50,9 +49,8 @@ Feature: Test basic usage of courses in app And I should find "Course 3" in the app Scenario: See my courses - When I enter the app - And I log in as "student1" - Then the header should be "Acceptance test site" in the app + Given I entered the app as "student1" + When the header should be "Acceptance test site" in the app And I press "My courses" in the app And I should find "Course 1" in the app And I should find "Course 2" in the app @@ -78,9 +76,8 @@ Feature: Test basic usage of courses in app And the header should be "Course 3" in the app Scenario: Search for a course - When I enter the app - And I log in as "student1" - And I press "Search courses" in the app + Given I entered the app as "student1" + When I press "Search courses" in the app And I set the field "Search" to "Course 4" in the app And I press "Search" "button" in the app Then I should find "Course 4" in the app @@ -102,8 +99,8 @@ Feature: Test basic usage of courses in app # TODO remove LMS UI steps in app tests Scenario: Links to actions in Timeline work for teachers/students # Configure assignment as teacher - When I enter the course "Course 1" as "teacher1" in the app - And I press "assignment" in the app + Given I entered the course "Course 1" as "teacher1" in the app + When I press "assignment" in the app And I press "Information" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app @@ -116,9 +113,8 @@ Feature: Test basic usage of courses in app And I close the browser tab opened by the app # Submit assignment as student - When I enter the app - And I log in as "student1" - And I press "Add submission" in the app + Given I entered the app as "student1" + When I press "Add submission" in the app Then the header should be "assignment" in the app And I should find "Test assignment description" in the app And I should find "No attempt" in the app @@ -135,9 +131,8 @@ Feature: Test basic usage of courses in app And I should find "Due:" in the app # Grade assignment as teacher - When I enter the app - And I log in as "teacher1" - And I press "Grade" in the app + Given I entered the app as "teacher1" + When I press "Grade" in the app Then the header should be "assignment" in the app And I should find "Test assignment description" in the app And I should find "Time remaining" in the app diff --git a/src/core/features/login/tests/behat/basic_usage.feature b/src/core/features/login/tests/behat/basic_usage.feature index 4230ddfa9..23f314947 100755 --- a/src/core/features/login/tests/behat/basic_usage.feature +++ b/src/core/features/login/tests/behat/basic_usage.feature @@ -63,9 +63,8 @@ Feature: Test basic usage of login in app And I should find "Wrong Site Address" in the app Scenario: Delete an account - When I enter the app - And I log in as "student1" - And I press the user menu button in the app + Given I entered the app as "student1" + When I press the user menu button in the app And I press "Log out" in the app And I wait the app to restart Then I should find "Acceptance test site" in the app diff --git a/src/core/features/mainmenu/tests/behat/mainmenu-311.feature b/src/core/features/mainmenu/tests/behat/mainmenu-311.feature index 955ff09ea..7de9fdce9 100644 --- a/src/core/features/mainmenu/tests/behat/mainmenu-311.feature +++ b/src/core/features/mainmenu/tests/behat/mainmenu-311.feature @@ -9,17 +9,15 @@ Feature: Main Menu opens the right page Scenario: Opens Site Home when defaulthomepage is set to Site Given the following config values are set as admin: | defaulthomepage | 0 | - When I enter the app - And I log in as "student" - Then "Site home" should be selected in the app + Given I entered the app as "student" + When "Site home" should be selected in the app And I should find "Available courses" in the app And "Site home" "text" should appear before "Dashboard" "text" in the ".core-tabs-bar" "css_element" Scenario: Opens Dashboard when defaulthomepage is set to Dashboard Given the following config values are set as admin: | defaulthomepage | 1 | - When I enter the app - And I log in as "student" - Then "Dashboard" should be selected in the app + Given I entered the app as "student" + When "Dashboard" should be selected in the app And I should find "Course overview" in the app And "Dashboard" "text" should appear before "Site home" "text" in the ".core-tabs-bar" "css_element" diff --git a/src/core/features/mainmenu/tests/behat/mainmenu.feature b/src/core/features/mainmenu/tests/behat/mainmenu.feature index 704568a40..d69a64651 100644 --- a/src/core/features/mainmenu/tests/behat/mainmenu.feature +++ b/src/core/features/mainmenu/tests/behat/mainmenu.feature @@ -16,9 +16,8 @@ Feature: Main Menu opens the right page Scenario: Opens Site Home when defaulthomepage is set to Site Given the following config values are set as admin: | defaulthomepage | 0 | - When I enter the app - And I log in as "student" - Then "Site home" should be selected in the app + Given I entered the app as "student" + When "Site home" should be selected in the app And I should find "Available courses" in the app And "Site home" "text" should appear before "Dashboard" "text" in the ".core-tabs-bar" "css_element" And "Home" "text" should appear before "My courses" "text" in the ".mainmenu-tabs" "css_element" @@ -27,9 +26,8 @@ Feature: Main Menu opens the right page Scenario: Opens Dashboard when defaulthomepage is set to Dashboard Given the following config values are set as admin: | defaulthomepage | 1 | - When I enter the app - And I log in as "student" - Then "Dashboard" should be selected in the app + Given I entered the app as "student" + When "Dashboard" should be selected in the app And I should find "Timeline" in the app And "Dashboard" "text" should appear before "Site home" "text" in the ".core-tabs-bar" "css_element" And "Home" "text" should appear before "My courses" "text" in the ".mainmenu-tabs" "css_element" @@ -38,8 +36,7 @@ Feature: Main Menu opens the right page Scenario: Opens My Courses when defaulthomepage is set to My Courses Given the following config values are set as admin: | defaulthomepage | 3 | - When I enter the app - And I log in as "student" - Then "My courses" near "Home" should be selected in the app + Given I entered the app as "student" + When "My courses" near "Home" should be selected in the app And I should find "Course 1" in the app And "My courses" "text" should appear before "Home" "text" in the ".mainmenu-tabs" "css_element" diff --git a/src/core/features/settings/tests/behat/settings_navigation.feature b/src/core/features/settings/tests/behat/settings_navigation.feature index d5cc521e2..e097556ba 100644 --- a/src/core/features/settings/tests/behat/settings_navigation.feature +++ b/src/core/features/settings/tests/behat/settings_navigation.feature @@ -7,8 +7,7 @@ Feature: It navigates properly within settings. | student1 | Scenario: Mobile navigation - Given I enter the app - And I log in as "student1" + Given I entered the app as "student1" # Settings When I press "More" in the app @@ -47,8 +46,7 @@ Feature: It navigates properly within settings. Then I should find "Total space used" in the app Scenario: Tablet navigation - Given I enter the app - And I log in as "student1" + Given I entered the app as "student1" And I change viewport size to "1200x640" # Settings diff --git a/src/core/features/siteplugins/tests/behat/plugins.feature b/src/core/features/siteplugins/tests/behat/plugins.feature index 5055fc707..1c5dca648 100644 --- a/src/core/features/siteplugins/tests/behat/plugins.feature +++ b/src/core/features/siteplugins/tests/behat/plugins.feature @@ -7,9 +7,8 @@ Feature: Plugins work properly. | studentusername | Scenario: See more menu button - When I enter the app - And I log in as "studentusername" - And I press the more menu button in the app + Given I entered the app as "studentusername" + When I press the more menu button in the app Then I should find "Moodle App Behat (auto-generated)" in the app When I press "Moodle App Behat (auto-generated)" in the app diff --git a/src/core/features/usertours/tests/behat/usertours.feature b/src/core/features/usertours/tests/behat/usertours.feature index 778c79845..7a24915de 100644 --- a/src/core/features/usertours/tests/behat/usertours.feature +++ b/src/core/features/usertours/tests/behat/usertours.feature @@ -17,9 +17,8 @@ Feature: User Tours work properly. | disableUserTours | false | Scenario: Acknowledge User Tours - When I enter the app - And I log in as "student1" - Then I should find "Explore your personal area" in the app + Given I entered the app as "student1" + When I should find "Explore your personal area" in the app But I should not find "Expand to explore" in the app When I press "Got it" in the app diff --git a/src/core/services/sites.ts b/src/core/services/sites.ts index 64c5af804..9cddd8b96 100644 --- a/src/core/services/sites.ts +++ b/src/core/services/sites.ts @@ -557,14 +557,14 @@ export class CoreSitesProvider { } // Add site to sites list. - this.addSite(siteId, siteUrl, token, info, privateToken, config, oauthId); + await this.addSite(siteId, siteUrl, token, info, privateToken, config, oauthId); this.sites[siteId] = candidateSite; if (login) { // Turn candidate site into current site. this.currentSite = candidateSite; // Store session. - this.login(siteId); + await this.login(siteId); } else if (this.currentSite && this.currentSite.getId() == siteId) { // Current site has just been updated, trigger the event. CoreEvents.trigger(CoreEvents.SITE_UPDATED, info, siteId); diff --git a/src/tests/behat/navigation_activities.feature b/src/tests/behat/navigation_activities.feature index 1c93c11be..c90b1fc6b 100644 --- a/src/tests/behat/navigation_activities.feature +++ b/src/tests/behat/navigation_activities.feature @@ -18,8 +18,8 @@ Feature: It navigates properly within activities. And I replace the arguments in "page" "content" Scenario: Navigates using deep links - When I enter the course "Course 1" as "student" in the app - And I press "Page" in the app + Given I entered the course "Course 1" as "student" in the app + When I press "Page" in the app And I press "Go to label" in the app Then I should find "Label description" in the app diff --git a/src/tests/behat/navigation_deeplinks.feature b/src/tests/behat/navigation_deeplinks.feature index b59d89794..4394a477f 100644 --- a/src/tests/behat/navigation_deeplinks.feature +++ b/src/tests/behat/navigation_deeplinks.feature @@ -24,9 +24,8 @@ Feature: It navigates properly using deep links. | defaulthomepage | 0 | | Scenario: Receive a push notification - When I enter the app - And I log in as "student2" - And I press the user menu button in the app + Given I entered the app as "student2" + When I press the user menu button in the app And I press "Log out" in the app And I wait the app to restart And I press "Add" in the app @@ -67,9 +66,8 @@ Feature: It navigates properly using deep links. And I should not find "Forum message" in the app Scenario: Open a link with a custom URL that calls WebServices for a logged out site - When I enter the app - And I log in as "student2" - And I press the user menu button in the app + Given I entered the app as "student2" + When I press the user menu button in the app And I press "Log out" in the app And I wait the app to restart And I open a custom link in the app for: diff --git a/src/tests/behat/navigation_externallinks.feature b/src/tests/behat/navigation_externallinks.feature index f49317ac2..7fbd9f133 100644 --- a/src/tests/behat/navigation_externallinks.feature +++ b/src/tests/behat/navigation_externallinks.feature @@ -20,8 +20,8 @@ Feature: It opens external links properly. # This test is flaky and may fail Scenario: Click an external link - When I enter the course "Course 1" as "student1" in the app - And I press "Test forum" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Test forum" in the app And I press "Forum topic" in the app And I press "moodle.org external link" in the app Then I should find "You are about to leave the app" in the app diff --git a/src/tests/behat/navigation_gestures.feature b/src/tests/behat/navigation_gestures.feature index 67deefcb3..7b02fd07a 100644 --- a/src/tests/behat/navigation_gestures.feature +++ b/src/tests/behat/navigation_gestures.feature @@ -21,8 +21,8 @@ Feature: It navigates using gestures. | student3 | C1 | student | Scenario: Swipe between participants - When I enter the course "Course 1" as "student1" in the app - And I press "Participants" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Participants" in the app And I press "Student First" in the app And I swipe to the left in the app Then I should find "Teacher First" in the app @@ -40,8 +40,8 @@ Feature: It navigates using gestures. Then I should find "Student First" in the app Scenario: Swipe between filtered participants - When I enter the course "Course 1" as "student1" in the app - And I press "Participants" in the app + Given I entered the course "Course 1" as "student1" in the app + When I press "Participants" in the app And I press "Search" in the app And I set the field "Search" to "student" in the app And I press "Search" "button" near "Clear search" in the app diff --git a/src/tests/behat/navigation_splitview.feature b/src/tests/behat/navigation_splitview.feature index 3b6e31359..74f331fbb 100644 --- a/src/tests/behat/navigation_splitview.feature +++ b/src/tests/behat/navigation_splitview.feature @@ -25,8 +25,7 @@ Feature: It navigates properly in pages with a split-view component. Scenario: Navigate in grades tab on mobile # Open user menu - Given I enter the app - And I log in as "student1" + Given I entered the app as "student1" And I press the user menu button in the app # Open grades page @@ -76,9 +75,8 @@ Feature: It navigates properly in pages with a split-view component. Scenario: Navigate in grades tab on tablet # Open user menu - Given I enter the app + Given I entered the app as "student1" And I change viewport size to "1200x640" - And I log in as "student1" And I press the user menu button in the app # Open grades page diff --git a/src/tests/behat/performance.feature b/src/tests/behat/performance.feature index 39a41c5d1..950dfee4e 100644 --- a/src/tests/behat/performance.feature +++ b/src/tests/behat/performance.feature @@ -81,13 +81,7 @@ Feature: Measure performance. Then "Login" should have taken less than 10 seconds Scenario: Open Activity - When I launch the app - Then I should see "Connect to Moodle" - But I should not see "Welcome to the Moodle App!" - - And I set the field "Your site" to "$WWWROOT" in the app - And I press "Connect to your site" in the app - And I log in as "student1" + Given I entered the app as "student1" Then I press "My courses" in the app And I should find "Course 1" in the app From 136fc96711dbc1ad389b41ccfdb315457639cb25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 9 May 2022 18:00:30 +0200 Subject: [PATCH 214/220] MOBILE-4061 behat: Use angular zone and improve blocking system --- .../tests/behat/behat_app.php | 87 +++++++++---- src/testing/services/behat-blocking.ts | 101 ++++++++-------- src/testing/services/behat-dom.ts | 114 +++++++++++++----- src/testing/services/behat-runtime.ts | 48 +------- 4 files changed, 203 insertions(+), 147 deletions(-) diff --git a/local-moodleappbehat/tests/behat/behat_app.php b/local-moodleappbehat/tests/behat/behat_app.php index 2ff4b7890..8b648c99f 100644 --- a/local-moodleappbehat/tests/behat/behat_app.php +++ b/local-moodleappbehat/tests/behat/behat_app.php @@ -113,7 +113,7 @@ class behat_app extends behat_base { } /** - * Opens the Moodle app in the browser and introduces the enters the site. + * Opens the Moodle App in the browser and introduces the enters the site. * * @Given /^I enter the app$/ * @throws DriverException Issue with configuration or feature file @@ -126,7 +126,7 @@ class behat_app extends behat_base { } /** - * Opens the Moodle app in the browser logged in as a user. + * Opens the Moodle App in the browser logged in as a user. * * @Given /^I enter(ed)? the app as "(.+)"$/ * @throws DriverException Issue with configuration or feature file @@ -140,7 +140,7 @@ class behat_app extends behat_base { } /** - * Opens the Moodle app in the browser. + * Opens the Moodle App in the browser. * * @Given /^I launch the app( runtime)?$/ * @throws DriverException Issue with configuration or feature file @@ -269,6 +269,8 @@ class behat_app extends behat_base { $this->evaluate_script("window.behat.getAngularInstance('ion-content', 'CoreSwipeNavigationDirective').$method()"); + $this->wait_for_pending_js(); + // Wait swipe animation to finish. $this->getSession()->wait(300); } @@ -327,7 +329,7 @@ class behat_app extends behat_base { } /** - * Fixes the Moodle admin settings to allow mobile app use (if not already correct). + * Fixes the Moodle admin settings to allow Moodle App use (if not already correct). * * @throws dml_exception If there is any problem changing Moodle settings */ @@ -517,7 +519,7 @@ class behat_app extends behat_base { } } - throw new DriverException('Moodle app not found in browser'); + throw new DriverException('Moodle App not found in browser'); }, false, 60); try { @@ -529,7 +531,7 @@ class behat_app extends behat_base { $this->execute_script('window.behatInit(' . json_encode($initOptions) . ');'); } catch (Exception $error) { - throw new DriverException('Moodle app not running or not running on Automated mode.'); + throw new DriverException('Moodle App not running or not running on Automated mode.'); } if ($restart) { @@ -548,7 +550,7 @@ class behat_app extends behat_base { return true; } - throw new DriverException('Moodle app not launched properly'); + throw new DriverException('Moodle App not launched properly'); }, false, 60); } @@ -591,7 +593,7 @@ class behat_app extends behat_base { if ($mainmenu) { return 'mainpage'; } - throw new DriverException('Moodle app main page not loaded after login'); + throw new DriverException('Moodle App main page not loaded after login'); }, false, 30); // Wait for JS to finish as well. @@ -700,7 +702,7 @@ class behat_app extends behat_base { * @param TableNode $data */ public function i_open_a_custom_link(TableNode $data) { - global $DB, $CFG; + global $DB; $data = $data->getColumnsHash()[0]; $title = array_keys($data)[0]; @@ -713,10 +715,33 @@ class behat_app extends behat_base { break; + case 'assign': + case 'bigbluebuttonbn': + case 'book': + case 'chat': + case 'choice': + case 'data': + case 'feedback': + case 'folder': case 'forum': - $forumdata = $DB->get_record('forum', ['name' => $data->forum]); - $cm = get_coursemodule_from_instance('forum', $forumdata->id); - $pageurl = "/mod/forum/view.php?id={$cm->id}"; + case 'glossary': + case 'h5pactivity': + case 'imscp': + case 'label': + case 'lesson': + case 'lti': + case 'page': + case 'quiz': + case 'resource': + case 'scorm': + case 'survey': + case 'url': + case 'wiki': + case 'workshop': + $name = $data->$title; + $module = $DB->get_record($title, ['name' => $name]); + $cm = get_coursemodule_from_instance($title, $module->id); + $pageurl = "/mod/$title/view.php?id={$cm->id}"; break; default: @@ -913,8 +938,8 @@ class behat_app extends behat_base { */ public function the_app_should_have_opened_a_browser_tab(bool $not = false, ?string $urlpattern = null) { $this->spin(function() use ($not, $urlpattern) { - $windownames = $this->getSession()->getWindowNames(); - $openedbrowsertab = count($windownames) === 2; + $windowNames = $this->getSession()->getWindowNames(); + $openedbrowsertab = count($windowNames) === 2; if ((!$not && !$openedbrowsertab) || ($not && $openedbrowsertab && is_null($urlpattern))) { throw new ExpectationException( @@ -926,10 +951,10 @@ class behat_app extends behat_base { } if (!is_null($urlpattern)) { - $this->getSession()->switchToWindow($windownames[1]); + $this->getSession()->switchToWindow($windowNames[1]); $windowurl = $this->getSession()->getCurrentUrl(); $windowhaspattern = preg_match("/$urlpattern/", $windowurl); - $this->getSession()->switchToWindow($windownames[0]); + $this->getSession()->switchToWindow($windowNames[0]); if ($not === $windowhaspattern) { throw new ExpectationException( @@ -954,11 +979,11 @@ class behat_app extends behat_base { * @throws DriverException If there aren't exactly 2 tabs open */ public function i_switch_to_the_browser_tab_opened_by_the_app() { - $names = $this->getSession()->getWindowNames(); - if (count($names) !== 2) { - throw new DriverException('Expected to see 2 tabs open, not ' . count($names)); + $windowNames = $this->getSession()->getWindowNames(); + if (count($windowNames) !== 2) { + throw new DriverException('Expected to see 2 tabs open, not ' . count($windowNames)); } - $this->getSession()->switchToWindow($names[1]); + $this->getSession()->switchToWindow($windowNames[1]); } /** @@ -984,8 +1009,8 @@ class behat_app extends behat_base { new ExpectationException('Forced cron tasks in the app took too long to complete', $session) ); - // Trigger Angular change detection - $session->executeScript('ngZone.run(() => {});'); + // Trigger Angular change detection. + $this->trigger_angular_change_detection(); } /** @@ -998,7 +1023,7 @@ class behat_app extends behat_base { $this->spin( function() use ($session) { - $session->executeScript('ngZone.run(() => {});'); + $this->trigger_angular_change_detection(); $nodes = $this->find_all('css', 'core-loading ion-spinner'); @@ -1169,8 +1194,16 @@ class behat_app extends behat_base { return $result; } + /** - * Opens a custom URL for automatic login and redirect from the mobile app (and waits to finish.) + * Trigger Angular change detection. + */ + private function trigger_angular_change_detection() { + $this->getSession()->executeScript('ngZone.run(() => {});'); + } + + /** + * Opens a custom URL for automatic login and redirect from the Moodle App (and waits to finish.) * * @param string $username Of the user that needs to be logged in. * @param string $path To redirect the user. @@ -1221,7 +1254,7 @@ class behat_app extends behat_base { } /** - * Opens a custom URL on the mobile app (and waits to finish.) + * Opens a custom URL on the Moodle App (and waits to finish.) * * @param string $path To navigate. * @param string $successXPath The XPath of the element to lookat after navigation. @@ -1236,7 +1269,7 @@ class behat_app extends behat_base { } /** - * Handles the custom URL on the mobile app (and waits to finish.) + * Handles the custom URL on the Moodle App (and waits to finish.) * * @param string $customurl To navigate. * @param string $successXPath The XPath of the element to lookat after navigation. @@ -1245,6 +1278,8 @@ class behat_app extends behat_base { // Instead of using evaluate_async_script, we wait for the path to load. $this->evaluate_script("return window.behat.handleCustomURL('$customurl')"); + $this->wait_for_pending_js(); + if (!empty($successXPath)) { // Wait until the page appears. $this->spin( diff --git a/src/testing/services/behat-blocking.ts b/src/testing/services/behat-blocking.ts index dbffa5a16..913ba00ab 100644 --- a/src/testing/services/behat-blocking.ts +++ b/src/testing/services/behat-blocking.ts @@ -13,7 +13,8 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { makeSingleton } from '@singletons'; +import { CoreUtils } from '@services/utils/utils'; +import { makeSingleton, NgZone } from '@singletons'; import { BehatTestsWindow, TestsBehatRuntime } from './behat-runtime'; /** @@ -26,6 +27,7 @@ export class TestsBehatBlockingService { protected recentMutation = false; protected lastMutation = 0; protected initialized = false; + protected keyIndex = 0; /** * Listen to mutations and override XML Requests. @@ -74,16 +76,23 @@ export class TestsBehatBlockingService { /** * Adds a pending key to the array. * - * @param key Key to add. + * @param key Key to add. It will be generated if none. + * @return Key name. */ - block(key: string): void { + block(key = ''): string { // Add a special DELAY entry whenever another entry is added. if (this.pendingList.length === 0) { this.pendingList.push('DELAY'); } + if (!key) { + key = 'generated-' + this.keyIndex; + this.keyIndex++; + } this.pendingList.push(key); TestsBehatRuntime.log('PENDING+: ' + this.pendingList); + + return key; } /** @@ -92,7 +101,7 @@ export class TestsBehatBlockingService { * * @param key Key to remove */ - unblock(key: string): void { + async unblock(key: string): Promise { // Remove the key immediately. this.pendingList = this.pendingList.filter((x) => x !== key); @@ -100,43 +109,32 @@ export class TestsBehatBlockingService { // If the only thing left is DELAY, then remove that as well, later... if (this.pendingList.length === 1) { - this.runAfterEverything(() => { - // Check there isn't a spinner... - this.checkUIBlocked(); + if (!document.hidden) { + // When tab is not active, ticks should be slower and may do Behat to fail. + // From Timers API: + // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers + // "This API does not guarantee that timers will run exactly on schedule. + // Delays due to CPU load, other tasks, etc, are to be expected." + await CoreUtils.nextTicks(10); + } - // Only remove it if the pending array is STILL empty after all that. - if (this.pendingList.length === 1) { - this.pendingList = []; - TestsBehatRuntime.log('PENDING-: ' + this.pendingList); - } - }); + // Check there isn't a spinner... + await this.checkUIBlocked(); + + // Only remove it if the pending array is STILL empty after all that. + if (this.pendingList.length === 1) { + this.pendingList = []; + TestsBehatRuntime.log('PENDING-: ' + this.pendingList); + } } } /** - * Adds a pending key to the array, but removes it after some setTimeouts finish. + * Adds a pending key to the array, but removes it after some ticks. */ - delay(): void { - this.block('...'); - this.unblock('...'); - } - - /** - * Run after several setTimeouts to ensure queued events are finished. - * - * @param target Function to run. - * @param count Number of times to do setTimeout (leave blank for 10). - */ - protected runAfterEverything(target: () => void, count = 10): void { - setTimeout(() => { - count--; - if (count === 0) { - target(); - - return; - } - this.runAfterEverything(target, count); - }, 0); + async delay(): Promise { + const key = this.block('forced-delay'); + this.unblock(key); } /** @@ -192,8 +190,9 @@ export class TestsBehatBlockingService { * Checks if a loading spinner is present and visible; if so, adds it to the pending array * (and if not, removes it). */ - protected checkUIBlocked(): void { - const blocked = document.querySelector('span.core-loading-spinner, ion-loading, .click-block-active'); + protected async checkUIBlocked(): Promise { + await CoreUtils.nextTick(); + const blocked = document.querySelector('div.core-loading-container, ion-loading, .click-block-active'); if (blocked?.offsetParent) { if (!this.waitingBlocked) { @@ -216,23 +215,25 @@ export class TestsBehatBlockingService { let requestIndex = 0; XMLHttpRequest.prototype.open = function(...args) { - const index = requestIndex++; - const key = 'httprequest-' + index; + NgZone.run(() => { + const index = requestIndex++; + const key = 'httprequest-' + index; - try { + try { // Add to the list of pending requests. - TestsBehatBlocking.block(key); + TestsBehatBlocking.block(key); - // Detect when it finishes and remove it from the list. - this.addEventListener('loadend', () => { + // Detect when it finishes and remove it from the list. + this.addEventListener('loadend', () => { + TestsBehatBlocking.unblock(key); + }); + + return realOpen.apply(this, args); + } catch (error) { TestsBehatBlocking.unblock(key); - }); - - return realOpen.apply(this, args); - } catch (error) { - TestsBehatBlocking.unblock(key); - throw error; - } + throw error; + } + }); }; } diff --git a/src/testing/services/behat-dom.ts b/src/testing/services/behat-dom.ts index eff06ab61..761806d69 100644 --- a/src/testing/services/behat-dom.ts +++ b/src/testing/services/behat-dom.ts @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +import { CoreUtils } from '@services/utils/utils'; +import { NgZone } from '@singletons'; import { TestsBehatBlocking } from './behat-blocking'; import { TestBehatElementLocator } from './behat-runtime'; @@ -409,30 +411,27 @@ export class TestsBehatDomUtils { * Make sure that an element is visible and wait to trigger the callback. * * @param element Element. - * @param callback Callback called when the element is visible, passing bounding box parameter. */ - protected static ensureElementVisible(element: HTMLElement, callback: (rect: DOMRect) => void): void { + protected static async ensureElementVisible(element: HTMLElement): Promise { const initialRect = element.getBoundingClientRect(); element.scrollIntoView(false); - requestAnimationFrame(() => { - const rect = element.getBoundingClientRect(); + return new Promise((resolve): void => { + requestAnimationFrame(() => { + const rect = element.getBoundingClientRect(); - if (initialRect.y !== rect.y) { - setTimeout(() => { - callback(rect); - }, 300); + if (initialRect.y !== rect.y) { + setTimeout(() => { + resolve(rect); + }, 300); - TestsBehatBlocking.delay(); + return; + } - return; - } - - callback(rect); + resolve(rect); + }); }); - - TestsBehatBlocking.delay(); }; /** @@ -440,16 +439,9 @@ export class TestsBehatDomUtils { * * @param element Element to press. */ - static pressElement(element: HTMLElement): void { - this.ensureElementVisible(element, (rect) => { - // Simulate a mouse click on the button. - const eventOptions = { - clientX: rect.left + rect.width / 2, - clientY: rect.top + rect.height / 2, - bubbles: true, - view: window, - cancelable: true, - }; + static async pressElement(element: HTMLElement): Promise { + NgZone.run(async () => { + const blockKey = TestsBehatBlocking.block(); // Events don't bubble up across Shadow DOM boundaries, and some buttons // may not work without doing this. @@ -459,6 +451,17 @@ export class TestsBehatDomUtils { element = parentElement; } + const rect = await this.ensureElementVisible(element); + + // Simulate a mouse click on the button. + const eventOptions: MouseEventInit = { + clientX: rect.left + rect.width / 2, + clientY: rect.top + rect.height / 2, + bubbles: true, + view: window, + cancelable: true, + }; + // There are some buttons in the app that don't respond to click events, for example // buttons using the core-supress-events directive. That's why we need to send both // click and mouse events. @@ -467,10 +470,65 @@ export class TestsBehatDomUtils { setTimeout(() => { element.dispatchEvent(new MouseEvent('mouseup', eventOptions)); element.click(); - }, 300); - // Mark busy until the button click finishes processing. - TestsBehatBlocking.delay(); + TestsBehatBlocking.unblock(blockKey); + }, 300); + }); + } + + /** + * Set an element value. + * + * @param element HTML to set. + * @param value Value to be set. + */ + static async setElementValue(element: HTMLElement, value: string): Promise { + NgZone.run(async () => { + const blockKey = TestsBehatBlocking.block(); + + // Functions to get/set value depending on field type. + let setValue = (text: string) => { + element.innerHTML = text; + }; + let getValue = () => element.innerHTML; + + if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) { + setValue = (text: string) => { + element.value = text; + }; + getValue = () => element.value; + } + + // Pretend we have cut and pasted the new text. + let event: InputEvent; + if (getValue() !== '') { + event = new InputEvent('input', { + bubbles: true, + view: window, + cancelable: true, + inputType: 'deleteByCut', + }); + + await CoreUtils.nextTick(); + setValue(''); + element.dispatchEvent(event); + } + + if (value !== '') { + event = new InputEvent('input', { + bubbles: true, + view: window, + cancelable: true, + inputType: 'insertFromPaste', + data: value, + }); + + await CoreUtils.nextTick(); + setValue(value); + element.dispatchEvent(event); + } + + TestsBehatBlocking.unblock(blockKey); }); } diff --git a/src/testing/services/behat-runtime.ts b/src/testing/services/behat-runtime.ts index 25fb88f35..97ba8a313 100644 --- a/src/testing/services/behat-runtime.ts +++ b/src/testing/services/behat-runtime.ts @@ -69,12 +69,16 @@ export class TestsBehatRuntime { * @return OK if successful, or ERROR: followed by message. */ static async handleCustomURL(url: string): Promise { + const blockKey = TestsBehatBlocking.block(); + try { await CoreCustomURLSchemes.handleCustomURL(url); return 'OK'; } catch (error) { return 'ERROR: ' + error.message; + } finally { + TestsBehatBlocking.unblock(blockKey); } } @@ -330,49 +334,7 @@ export class TestsBehatRuntime { return 'ERROR: No element matches field to set.'; } - // Functions to get/set value depending on field type. - let setValue = (text: string) => { - found.innerHTML = text; - }; - let getValue = () => found.innerHTML; - - if (found instanceof HTMLInputElement || found instanceof HTMLTextAreaElement) { - setValue = (text: string) => { - found.value = text; - }; - getValue = () => found.value; - } - - // Pretend we have cut and pasted the new text. - let event: InputEvent; - if (getValue() !== '') { - event = new InputEvent('input', { - bubbles: true, - view: window, - cancelable: true, - inputType: 'deleteByCut', - }); - - setTimeout(() => { - setValue(''); - found.dispatchEvent(event); - }, 0); - } - - if (value !== '') { - event = new InputEvent('input', { - bubbles: true, - view: window, - cancelable: true, - inputType: 'insertFromPaste', - data: value, - }); - - setTimeout(() => { - setValue(value); - found.dispatchEvent(event); - }, 0); - } + TestsBehatDomUtils.setElementValue(found, value); return 'OK'; } From cb1a611b5e57734cdf74a3b4b5c98641fb2f2526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 10 May 2022 13:29:30 +0200 Subject: [PATCH 215/220] MOBILE-4061 behat: Fix repeated tests scenario names --- src/addons/mod/assign/tests/behat/navigation.feature | 4 ++-- src/addons/mod/chat/tests/behat/navigation.feature | 2 +- src/addons/mod/forum/tests/behat/navigation.feature | 4 ++-- src/addons/mod/glossary/tests/behat/navigation.feature | 4 ++-- src/core/features/courses/tests/behat/basic_usage-311.feature | 2 +- src/core/features/courses/tests/behat/basic_usage.feature | 2 ++ .../features/settings/tests/behat/settings_navigation.feature | 4 ++-- src/tests/behat/navigation_externallinks.feature | 1 - 8 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/addons/mod/assign/tests/behat/navigation.feature b/src/addons/mod/assign/tests/behat/navigation.feature index 12ee6c291..487a9c34d 100644 --- a/src/addons/mod/assign/tests/behat/navigation.feature +++ b/src/addons/mod/assign/tests/behat/navigation.feature @@ -35,7 +35,7 @@ Feature: Test assignments navigation | assignment | student1 | Lorem | | assignment | student3 | Ipsum | - Scenario: Mobile navigation + Scenario: Mobile navigation on assignment Given I entered the course "Course 1" as "teacher1" in the app # Initial status @@ -149,7 +149,7 @@ Feature: Test assignments navigation But I should not find "First Student" in the app And I should not find "Second Student" in the app - Scenario: Tablet navigation + Scenario: Tablet navigation on assignment Given I entered the course "Course 1" as "teacher1" in the app And I change viewport size to "1200x640" diff --git a/src/addons/mod/chat/tests/behat/navigation.feature b/src/addons/mod/chat/tests/behat/navigation.feature index 0b757fb3a..8bca1e498 100644 --- a/src/addons/mod/chat/tests/behat/navigation.feature +++ b/src/addons/mod/chat/tests/behat/navigation.feature @@ -25,7 +25,7 @@ Feature: Test chat navigation And I press "Send" in the app Then I should find "Test message" in the app - Scenario: Tablet navigation + Scenario: Tablet navigation on chat Given I entered the course "Course 1" as "student2" in the app And I change viewport size to "1200x640" diff --git a/src/addons/mod/forum/tests/behat/navigation.feature b/src/addons/mod/forum/tests/behat/navigation.feature index 0ecbb040b..f3a9a4f7a 100644 --- a/src/addons/mod/forum/tests/behat/navigation.feature +++ b/src/addons/mod/forum/tests/behat/navigation.feature @@ -41,7 +41,7 @@ Feature: Test forum navigation | Discussion 04 | Discussion 04 | Discussion 04 first reply | | Discussion 05 | Discussion 05 | Discussion 05 first reply | - Scenario: Mobile navigation + Scenario: Mobile navigation on forum Given I entered the course "Course 1" as "student1" in the app # By last reply @@ -138,7 +138,7 @@ Feature: Test forum navigation # When I swipe to the left in the app # Then I should find "Discussion 20 message" in the app - Scenario: Tablet navigation + Scenario: Tablet navigation on forum Given I entered the course "Course 1" as "student1" in the app And I change viewport size to "1200x640" diff --git a/src/addons/mod/glossary/tests/behat/navigation.feature b/src/addons/mod/glossary/tests/behat/navigation.feature index cd807e65b..77d1bd1b8 100644 --- a/src/addons/mod/glossary/tests/behat/navigation.feature +++ b/src/addons/mod/glossary/tests/behat/navigation.feature @@ -87,7 +87,7 @@ Feature: Test glossary navigation | glossary | Tangerine | Tangerine is a fruit | student1 | | glossary | Watermelon | Watermelon is a fruit | student2 | - Scenario: Mobile navigation + Scenario: Mobile navigation on glossary Given I entered the course "Course 1" as "student1" in the app # Alphabetically @@ -194,7 +194,7 @@ Feature: Test glossary navigation When I swipe to the left in the app Then I should find "Acerola is a fruit" in the app - Scenario: Tablet navigation + Scenario: Tablet navigation on glossary Given I entered the course "Course 1" as "student1" in the app And I change viewport size to "1200x640" diff --git a/src/core/features/courses/tests/behat/basic_usage-311.feature b/src/core/features/courses/tests/behat/basic_usage-311.feature index 40f642f36..3b0a4a52c 100755 --- a/src/core/features/courses/tests/behat/basic_usage-311.feature +++ b/src/core/features/courses/tests/behat/basic_usage-311.feature @@ -34,7 +34,7 @@ Feature: Test basic usage of courses in app | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | | assign | C1 | assign1 | assignment | Test assignment description | 1 | - Scenario: "Dashboard" tab displayed in >= 3.3 sites + Scenario: "Dashboard" tab displayed Given I entered the app as "student1" When I should see "Dashboard" And the header should be "Acceptance test site" in the app diff --git a/src/core/features/courses/tests/behat/basic_usage.feature b/src/core/features/courses/tests/behat/basic_usage.feature index 313e9b063..c76f34d9c 100755 --- a/src/core/features/courses/tests/behat/basic_usage.feature +++ b/src/core/features/courses/tests/behat/basic_usage.feature @@ -34,6 +34,7 @@ Feature: Test basic usage of courses in app | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | | assign | C1 | assign1 | assignment | Test assignment description | 1 | + @lms_from4.0 Scenario: "Dashboard" tab displayed Given I entered the app as "student1" When I should see "Dashboard" @@ -48,6 +49,7 @@ Feature: Test basic usage of courses in app And I should find "Course 2" in the app And I should find "Course 3" in the app + @lms_from4.0 Scenario: See my courses Given I entered the app as "student1" When the header should be "Acceptance test site" in the app diff --git a/src/core/features/settings/tests/behat/settings_navigation.feature b/src/core/features/settings/tests/behat/settings_navigation.feature index e097556ba..9096b1138 100644 --- a/src/core/features/settings/tests/behat/settings_navigation.feature +++ b/src/core/features/settings/tests/behat/settings_navigation.feature @@ -6,7 +6,7 @@ Feature: It navigates properly within settings. | username | | student1 | - Scenario: Mobile navigation + Scenario: Mobile navigation on settings Given I entered the app as "student1" # Settings @@ -45,7 +45,7 @@ Feature: It navigates properly within settings. And I press "Manage downloads" in the app Then I should find "Total space used" in the app - Scenario: Tablet navigation + Scenario: Tablet navigation on settings Given I entered the app as "student1" And I change viewport size to "1200x640" diff --git a/src/tests/behat/navigation_externallinks.feature b/src/tests/behat/navigation_externallinks.feature index 7fbd9f133..35fcf6564 100644 --- a/src/tests/behat/navigation_externallinks.feature +++ b/src/tests/behat/navigation_externallinks.feature @@ -18,7 +18,6 @@ Feature: It opens external links properly. | forum | user | name | message | | Test forum | student1 | Forum topic | See moodle.org external link | - # This test is flaky and may fail Scenario: Click an external link Given I entered the course "Course 1" as "student1" in the app When I press "Test forum" in the app From cc3c8906c65dee8110f78d7e2a138c66542f4328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 11 May 2022 11:57:07 +0200 Subject: [PATCH 216/220] MOBILE-4061 behat: Add shortcuts to enter activities --- .../tests/behat/behat_app.php | 40 +++++++++- .../tests/behat/basic_usage-310.feature | 6 +- .../assign/tests/behat/basic_usage.feature | 36 ++++----- .../mod/chat/tests/behat/basic_usage.feature | 16 ++-- .../mod/chat/tests/behat/navigation.feature | 3 +- .../tests/behat/basic_usage-311.feature | 8 +- .../choice/tests/behat/basic_usage.feature | 30 +++----- .../mod/forum/tests/behat/basic_usage.feature | 75 ++++++++----------- .../mod/quiz/tests/behat/basic_usage.feature | 20 ++--- .../quiz/tests/behat/quiz_navigation.feature | 3 +- .../tests/behat/basic_usage-310.feature | 5 +- .../courses/tests/behat/basic_usage.feature | 5 +- .../behat/navigation_externallinks.feature | 5 +- 13 files changed, 120 insertions(+), 132 deletions(-) diff --git a/local-moodleappbehat/tests/behat/behat_app.php b/local-moodleappbehat/tests/behat/behat_app.php index 8b648c99f..16f3a52a6 100644 --- a/local-moodleappbehat/tests/behat/behat_app.php +++ b/local-moodleappbehat/tests/behat/behat_app.php @@ -566,7 +566,7 @@ class behat_app extends behat_base { global $CFG; - $this->i_set_the_field_in_the_app('Your site', $CFG->wwwroot); + $this->i_set_the_field_in_the_app('Your site', $CFG->behat_wwwroot); $this->i_press_in_the_app('"Connect to your site"'); $this->wait_for_pending_js(); } @@ -603,7 +603,7 @@ class behat_app extends behat_base { /** * User enters a course in the app. * - * @Given /^I enter(ed)? the course "(.+?)"(?: as "(.+)")? in the app$/ + * @Given /^I enter(ed)? the course "([^"]+)"(?: as "([^"]+)")? in the app$/ * @param string $coursename Course name * @throws DriverException If the button push doesn't work */ @@ -622,8 +622,42 @@ class behat_app extends behat_base { } else { $this->open_moodleapp_custom_url("/course/view.php?id=$courseid", '//page-core-course-index'); } + } + /** + * User enters an activity in a course in the app. + * + * @Given /^I enter(ed)? the (.+) activity "([^"]+)" on course "([^"]+)"(?: as "([^"]+)")? in the app$/ + * @param string $coursename Course name + * @throws DriverException If the button push doesn't work + */ + public function i_enter_the_activity_in_the_app(bool $unused, string $activity, string $activityname, string $coursename, ?string $username = null) { + global $DB; + $courseid = $DB->get_field('course', 'id', [ 'fullname' => $coursename]); + if (!$courseid) { + throw new DriverException("Course '$coursename' not found"); + } + + if ($activity === 'assignment') { + $activity = 'assign'; + } + + $module = $DB->get_record($activity, ['name' => $activityname, 'course' => $courseid ]); + if (!$module) { + throw new DriverException("'$activityname' activity '$activityname' not found"); + } + + $cm = get_coursemodule_from_instance($activity, $module->id); + $pageurl = "/mod/$activity/view.php?id={$cm->id}"; + + if ($username) { + $this->i_launch_the_app(); + + $this->open_moodleapp_custom_login_url($username, $pageurl); + } else { + $this->open_moodleapp_custom_url($pageurl); + } } /** @@ -660,7 +694,7 @@ class behat_app extends behat_base { $module = $DB->get_record('course_modules', ['idnumber' => $data->module]); $discussion = $DB->get_record('forum_discussions', ['name' => $data->discussion]); $notification = json_encode([ - 'site' => md5($CFG->wwwroot . $data->username), + 'site' => md5($CFG->behat_wwwroot . $data->username), 'courseid' => $discussion->course, 'moodlecomponent' => 'mod_forum', 'name' => 'posts', diff --git a/src/addons/mod/assign/tests/behat/basic_usage-310.feature b/src/addons/mod/assign/tests/behat/basic_usage-310.feature index cdd88aeef..532f7a134 100755 --- a/src/addons/mod/assign/tests/behat/basic_usage-310.feature +++ b/src/addons/mod/assign/tests/behat/basic_usage-310.feature @@ -21,8 +21,7 @@ Feature: Test basic usage of assignment activity in app Scenario: View assign description, due date & View list of student submissions (as teacher) & View own submission or student submission # Create, edit and submit as a student - Given I entered the course "Course 1" as "student1" in the app - When I press "assignment1" in the app + Given I entered the assign activity "assignment1" on course "Course 1" as "student1" in the app Then the header should be "assignment1" in the app And I should find "Test assignment description1" in the app And I should find "Due date" in the app @@ -47,8 +46,7 @@ Feature: Test basic usage of assignment activity in app And I should find "Submission test edited" in the app # View as a teacher - Given I entered the course "Course 1" as "teacher1" in the app - When I press "assignment1" in the app + Given I entered the assign activity "assignment1" on course "Course 1" as "teacher1" in the app Then the header should be "assignment1" in the app When I press "Submitted" in the app diff --git a/src/addons/mod/assign/tests/behat/basic_usage.feature b/src/addons/mod/assign/tests/behat/basic_usage.feature index 9e26048be..ec41e1017 100755 --- a/src/addons/mod/assign/tests/behat/basic_usage.feature +++ b/src/addons/mod/assign/tests/behat/basic_usage.feature @@ -22,8 +22,7 @@ Feature: Test basic usage of assignment activity in app @lms_from3.11 Scenario: View assign description, due date & View list of student submissions (as teacher) & View own submission or student submission # Create, edit and submit as a student - Given I entered the course "Course 1" as "student1" in the app - When I press "assignment1" in the app + Given I entered the assign activity "assignment1" on course "Course 1" as "student1" in the app Then the header should be "assignment1" in the app And I should find "Test assignment description1" in the app And I should find "Due:" in the app @@ -48,8 +47,7 @@ Feature: Test basic usage of assignment activity in app And I should find "Submission test edited" in the app # View as a teacher - Given I entered the course "Course 1" as "teacher1" in the app - When I press "assignment1" in the app + Given I entered the assign activity "assignment1" on course "Course 1" as "teacher1" in the app Then the header should be "assignment1" in the app When I press "Submitted" in the app @@ -62,18 +60,16 @@ Feature: Test basic usage of assignment activity in app Scenario: Edit/Add submission (online text) & Add new attempt from previous submission & Submit for grading # Submit first attempt as a student - Given I entered the course "Course 1" as "student1" in the app - And I press "assignment1" in the app - And I press "Add submission" in the app - And I set the field "Online text submissions" to "Submission test 1st attempt" in the app + Given I entered the assign activity "assignment1" on course "Course 1" as "student1" in the app + When I press "Add submission" in the app + Then I set the field "Online text submissions" to "Submission test 1st attempt" in the app And I press "Save" in the app And I press "Submit assignment" in the app And I press "OK" in the app # Allow more attempts as a teacher - Given I entered the course "Course 1" as "teacher1" in the app - When I press "assignment1" in the app - And I press "Participants" in the app + Given I entered the assign activity "assignment1" on course "Course 1" as "teacher1" in the app + When I press "Participants" in the app And I press "Student student" near "assignment1" in the app And I press "Grade" in the app And I press "Allow another attempt" in the app @@ -82,8 +78,7 @@ Feature: Test basic usage of assignment activity in app And I should find "Not graded" in the app # Submit second attempt as a student - Given I entered the course "Course 1" as "student1" in the app - When I press "assignment1" in the app + Given I entered the assign activity "assignment1" on course "Course 1" as "student1" in the app Then I should find "Reopened" in the app And I should find "2 out of Unlimited" in the app And I should find "Add a new attempt based on previous submission" in the app @@ -100,17 +95,15 @@ Feature: Test basic usage of assignment activity in app And I press "OK" in the app # View second attempt as a teacher - Given I entered the course "Course 1" as "teacher1" in the app - When I press "assignment1" in the app - And I press "Participants" in the app + Given I entered the assign activity "assignment1" on course "Course 1" as "teacher1" in the app + When I press "Participants" in the app And I press "Student student" near "assignment1" in the app Then I should find "Online text submissions" in the app And I should find "Submission test 2nd attempt" in the app Scenario: Add submission offline (online text) & Submit for grading offline & Sync submissions - Given I entered the course "Course 1" as "student1" in the app - When I press "assignment1" in the app - And I press "Add submission" in the app + Given I entered the assign activity "assignment1" on course "Course 1" as "student1" in the app + When I press "Add submission" in the app And I switch offline mode to "true" And I set the field "Online text submissions" to "Submission test" in the app And I press "Save" in the app @@ -127,9 +120,8 @@ Feature: Test basic usage of assignment activity in app But I should not find "This Assignment has offline data to be synchronised." in the app Scenario: Edit an offline submission before synchronising it - Given I entered the course "Course 1" as "student1" in the app - When I press "assignment1" in the app - And I press "Add submission" in the app + Given I entered the assign activity "assignment1" on course "Course 1" as "student1" in the app + When I press "Add submission" in the app And I switch offline mode to "true" And I set the field "Online text submissions" to "Submission test original offline" in the app And I press "Save" in the app diff --git a/src/addons/mod/chat/tests/behat/basic_usage.feature b/src/addons/mod/chat/tests/behat/basic_usage.feature index d739a2df9..35a4972f6 100755 --- a/src/addons/mod/chat/tests/behat/basic_usage.feature +++ b/src/addons/mod/chat/tests/behat/basic_usage.feature @@ -21,8 +21,7 @@ Feature: Test basic usage of chat in app Scenario: Receive and send messages & See connected users, beep and talk to # Send messages as student1 - Given I entered the course "Course 1" as "student1" in the app - When I press "Test chat name" in the app + Given I entered the chat activity "Test chat name" on course "Course 1" as "student1" in the app Then I should find "Enter the chat" in the app And I should find "Past sessions" in the app @@ -37,8 +36,7 @@ Feature: Test basic usage of chat in app And I should find "I am David" in the app # Read messages, view connected users, send beep and reply as student2 - Given I entered the course "Course 1" as "student2" in the app - When I press "Test chat name" in the app + Given I entered the chat activity "Test chat name" on course "Course 1" as "student2" in the app And I press "Enter the chat" in the app Then I should find "Hi!" in the app And I should find "I am David" in the app @@ -55,9 +53,8 @@ Feature: Test basic usage of chat in app Scenario: Past sessions shown # Send messages as student1 - Given I entered the course "Course 1" as "student1" in the app - And I press "Test chat name" in the app - And I press "Enter the chat" in the app + Given I entered the chat activity "Test chat name" on course "Course 1" as "student1" in the app + When I press "Enter the chat" in the app And I set the field "New message" to "Hi!" in the app And I press "Send" in the app Then I should find "Hi!" in the app @@ -67,9 +64,8 @@ Feature: Test basic usage of chat in app Then I should find "I am David" in the app # Read messages from past sessions as student2 - Given I entered the course "Course 1" as "student2" in the app - When I press "Test chat name" in the app - And I press "Past sessions" in the app + Given I entered the chat activity "Test chat name" on course "Course 1" as "student2" in the app + When I press "Past sessions" in the app And I press "Show incomplete sessions" in the app And I press "david student" near "(2)" in the app Then I should find "Hi!" in the app diff --git a/src/addons/mod/chat/tests/behat/navigation.feature b/src/addons/mod/chat/tests/behat/navigation.feature index 8bca1e498..3490ea6f0 100644 --- a/src/addons/mod/chat/tests/behat/navigation.feature +++ b/src/addons/mod/chat/tests/behat/navigation.feature @@ -18,8 +18,7 @@ Feature: Test chat navigation | chat | Test chat name | Test chat | C1 | chat | 0 | # Create sessions # TODO use generator instead - And I entered the course "Course 1" as "student1" in the app - And I press "Test chat name" in the app + And I entered the chat activity "Test chat name" on course "Course 1" as "student1" in the app And I press "Enter the chat" in the app And I set the field "New message" to "Test message" in the app And I press "Send" in the app diff --git a/src/addons/mod/choice/tests/behat/basic_usage-311.feature b/src/addons/mod/choice/tests/behat/basic_usage-311.feature index 6ce9f1e60..5030a7f2e 100755 --- a/src/addons/mod/choice/tests/behat/basic_usage-311.feature +++ b/src/addons/mod/choice/tests/behat/basic_usage-311.feature @@ -22,15 +22,13 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | - And I entered the course "Course 1" as "student1" in the app - Then I press "Choice name" in the app - And I select "Option 2" in the app + And I entered the choice activity "Choice name" on course "Course 1" as "student1" in the app + Then I select "Option 2" in the app And I press "Save my choice" in the app And I press "OK" in the app # Download answers as teacher - Given I entered the course "Course 1" as "teacher1" in the app - When I press "Choice name" in the app + Given I entered the choice activity "Choice name" on course "Course 1" as "teacher1" in the app Then I should find "Test choice description" in the app When I press "Information" in the app diff --git a/src/addons/mod/choice/tests/behat/basic_usage.feature b/src/addons/mod/choice/tests/behat/basic_usage.feature index 8585a6ab4..753181599 100755 --- a/src/addons/mod/choice/tests/behat/basic_usage.feature +++ b/src/addons/mod/choice/tests/behat/basic_usage.feature @@ -21,9 +21,8 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - Given I entered the course "Course 1" as "student1" in the app - When I press "Test single choice name" in the app - And I select "Option 1" in the app + And I entered the choice activity "Test single choice name" on course "Course 1" as "student1" in the app + When I select "Option 1" in the app And I select "Option 2" in the app And I press "Save my choice" in the app Then I should find "Are you sure" in the app @@ -44,9 +43,8 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test multi choice name | Test multi choice description | C1 | choice2 | Option 1, Option 2, Option 3 | 1 | 1 | 1 | - Given I entered the course "Course 1" as "student1" in the app - When I press "Test multi choice name" in the app - And I select "Option 1" in the app + And I entered the choice activity "Test multi choice name" on course "Course 1" as "student1" in the app + When I select "Option 1" in the app And I select "Option 2" in the app And I press "Save my choice" in the app Then I should find "Option 1: 1" in the app @@ -72,9 +70,8 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - Given I entered the course "Course 1" as "student1" in the app - When I press "Test single choice name" in the app - And I select "Option 1" in the app + And I entered the choice activity "Test single choice name" on course "Course 1" as "student1" in the app + When I select "Option 1" in the app And I switch offline mode to "true" And I select "Option 2" in the app And I press "Save my choice" in the app @@ -104,9 +101,8 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | allowmultiple | allowupdate | showresults | | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | - Given I entered the course "Course 1" as "student1" in the app - When I press "Test single choice name" in the app - And I select "Option 1" in the app + And I entered the choice activity "Test single choice name" on course "Course 1" as "student1" in the app + When I select "Option 1" in the app And I switch offline mode to "true" And I select "Option 2" in the app And I press "Save my choice" in the app @@ -133,7 +129,7 @@ Feature: Test basic usage of choice activity in app | choice | Test single choice name | Test single choice description | C1 | choice1 | Option 1, Option 2, Option 3 | 0 | 0 | 1 | Given I entered the course "Course 1" as "student1" in the app When I press "Course downloads" in the app - And I press "Download" within "Test single choice name" "ion-item" in the app + When I press "Download" within "Test single choice name" "ion-item" in the app Then I should find "Downloaded" within "Test single choice name" "ion-item" in the app And I press the back button in the app @@ -171,15 +167,13 @@ Feature: Test basic usage of choice activity in app Given the following "activities" exist: | activity | name | intro | course | idnumber | option | | choice | Choice name | Test choice description | C1 | choice1 | Option 1, Option 2, Option 3 | - And I entered the course "Course 1" as "student1" in the app - Then I press "Choice name" in the app - And I select "Option 2" in the app + And I entered the choice activity "Choice name" on course "Course 1" as "student1" in the app + When I select "Option 2" in the app And I press "Save my choice" in the app And I press "OK" in the app # Download answers as teacher - Given I entered the course "Course 1" as "teacher1" in the app - When I press "Choice name" in the app + Given I entered the choice activity "Choice name" on course "Course 1" as "teacher1" in the app Then I should find "Test choice description" in the app When I press "Information" in the app diff --git a/src/addons/mod/forum/tests/behat/basic_usage.feature b/src/addons/mod/forum/tests/behat/basic_usage.feature index 20b075d96..ddf3e4990 100755 --- a/src/addons/mod/forum/tests/behat/basic_usage.feature +++ b/src/addons/mod/forum/tests/behat/basic_usage.feature @@ -25,9 +25,8 @@ Feature: Test basic usage of forum activity in app | forum | Test forum name | Test forum | C1 | forum | 0 | 1 | 1 | Scenario: Create new discussion - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I press "Add discussion topic" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I press "Add discussion topic" in the app And I set the field "Subject" to "My happy subject" in the app And I set the field "Message" to "An awesome message" in the app And I press "Post to forum" in the app @@ -37,9 +36,8 @@ Feature: Test basic usage of forum activity in app Then I should find "An awesome message" in the app Scenario: Reply a post - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I press "Add discussion topic" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app @@ -53,9 +51,8 @@ Feature: Test basic usage of forum activity in app And I should find "ReplyMessage" in the app Scenario: Star and pin discussions (student) - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I press "Add discussion topic" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I press "Add discussion topic" in the app And I set the field "Subject" to "starred subject" in the app And I set the field "Message" to "starred message" in the app And I press "Post to forum" in the app @@ -87,9 +84,8 @@ Feature: Test basic usage of forum activity in app Then I should find "normal message" in the app Scenario: Star and pin discussions (teacher) - Given I entered the course "Course 1" as "teacher1" in the app - When I press "Test forum name" in the app - And I press "Add discussion topic" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "teacher1" in the app + When I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test star" in the app And I set the field "Message" to "Auto-test star message" in the app And I press "Post to forum" in the app @@ -117,9 +113,8 @@ Feature: Test basic usage of forum activity in app And I should find "Auto-test pin" in the app Scenario: Edit a not sent reply offline - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I press "Add discussion topic" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -150,9 +145,8 @@ Feature: Test basic usage of forum activity in app And I should not find "This Discussion has offline data to be synchronised" in the app Scenario: Edit a not sent new discussion offline - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I switch offline mode to "true" + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I switch offline mode to "true" And I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app @@ -173,9 +167,8 @@ Feature: Test basic usage of forum activity in app And I should find "Auto-test message edited" in the app Scenario: Edit a forum post (only online) - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I press "Add discussion topic" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -200,9 +193,8 @@ Feature: Test basic usage of forum activity in app # TODO Fix this test in all Moodle versions Scenario: Delete a forum post (only online) - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I press "Add discussion topic" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -233,9 +225,8 @@ Feature: Test basic usage of forum activity in app Then I should not find "Auto-test" in the app Scenario: Add/view ratings - Given I entered the course "Course 1" as "student1" in the app - And I press "Test forum name" in the app - And I press "Add discussion topic" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I press "Add discussion topic" in the app And I set the field "Subject" to "Auto-test" in the app And I set the field "Message" to "Auto-test message" in the app And I press "Post to forum" in the app @@ -247,9 +238,8 @@ Feature: Test basic usage of forum activity in app And I press "Post to forum" in the app Then I should find "test2" "ion-card" in the app - Given I entered the course "Course 1" as "teacher1" in the app - When I press "Test forum name" in the app - And I press "Auto-test" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "teacher1" in the app + When I press "Auto-test" in the app Then I should find "Reply" in the app When I press "None" near "Auto-test message" in the app @@ -274,17 +264,15 @@ Feature: Test basic usage of forum activity in app And I should find "Average of ratings: 0" in the app But I should not find "Average of ratings: -" in the app - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I press "Auto-test" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I press "Auto-test" in the app Then I should find "Average of ratings: 1" in the app And I should find "Average of ratings: 0" in the app But I should not find "Average of ratings: -" in the app Scenario: Reply a post offline - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I press "Add discussion topic" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app And I press "Post to forum" in the app @@ -312,9 +300,8 @@ Feature: Test basic usage of forum activity in app But I should not find "Not sent" in the app Scenario: New discussion offline & Sync Forum - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I switch offline mode to "true" + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I switch offline mode to "true" And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app @@ -335,9 +322,8 @@ Feature: Test basic usage of forum activity in app And I should not find "This Forum has offline data to be synchronised." in the app Scenario: New discussion offline & Auto-sync forum - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I switch offline mode to "true" + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I switch offline mode to "true" And I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject" in the app And I set the field "Message" to "DiscussionMessage" in the app @@ -358,9 +344,8 @@ Feature: Test basic usage of forum activity in app And I should not find "This Forum has offline data to be synchronised." in the app Scenario: Prefetch - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum name" in the app - And I press "Add discussion topic" in the app + Given I entered the forum activity "Test forum name" on course "Course 1" as "student1" in the app + When I press "Add discussion topic" in the app And I set the field "Subject" to "DiscussionSubject 1" in the app And I set the field "Message" to "DiscussionMessage 1" in the app And I press "Post to forum" in the app diff --git a/src/addons/mod/quiz/tests/behat/basic_usage.feature b/src/addons/mod/quiz/tests/behat/basic_usage.feature index c20850298..73479ebc3 100755 --- a/src/addons/mod/quiz/tests/behat/basic_usage.feature +++ b/src/addons/mod/quiz/tests/behat/basic_usage.feature @@ -56,9 +56,8 @@ Feature: Attempt a quiz in app | TF9 | 7 | Scenario: View a quiz entry page (attempts, status, etc.) - Given I entered the course "Course 1" as "student1" in the app - When I press "Quiz 1" in the app - And I press "Attempt quiz now" in the app + Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app + When I press "Attempt quiz now" in the app Then I should find "Text of the first question" in the app But I should not find "Text of the second question" in the app @@ -106,9 +105,8 @@ Feature: Attempt a quiz in app And I should find "Question 2" in the app Scenario: Attempt a quiz (all question types) - Given I entered the course "Course 1" as "student1" in the app - When I press "Quiz 2" in the app - And I press "Attempt quiz now" in the app + Given I entered the quiz activity "Quiz 2" on course "Course 1" as "student1" in the app + When I press "Attempt quiz now" in the app And I press "Four" in the app And I press "Three" in the app And I press "Next" near "Quiz 2" in the app @@ -143,9 +141,8 @@ Feature: Attempt a quiz in app And I should find "Not yet graded" in the app Scenario: Submit a quiz & Review a quiz attempt - Given I entered the course "Course 1" as "student1" in the app - When I press "Quiz 1" in the app - And I press "Attempt quiz now" in the app + Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app + When I press "Attempt quiz now" in the app And I press "True" in the app And I press "Next" near "Question 1" in the app And I press "False" in the app @@ -154,9 +151,8 @@ Feature: Attempt a quiz in app And I press "OK" in the app Then I should find "Review" in the app - Given I entered the course "Course 1" as "teacher1" in the app - When I press "Quiz 1" in the app - And I press "Information" in the app + Given I entered the quiz activity "Quiz 1" on course "Course 1" as "teacher1" in the app + When I press "Information" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" diff --git a/src/addons/mod/quiz/tests/behat/quiz_navigation.feature b/src/addons/mod/quiz/tests/behat/quiz_navigation.feature index a81c5d0a3..8ecb4e422 100644 --- a/src/addons/mod/quiz/tests/behat/quiz_navigation.feature +++ b/src/addons/mod/quiz/tests/behat/quiz_navigation.feature @@ -30,8 +30,7 @@ Feature: Attempt a quiz in app | TF2 | 2 | Scenario: Next and previous navigation - Given I entered the course "Course 1" as "student1" in the app - When I press "Quiz 1" in the app + Given I entered the quiz activity "Quiz 1" on course "Course 1" as "student1" in the app And I press "Attempt quiz now" in the app Then I should find "Text of the first question" in the app But I should not find "Text of the second question" in the app diff --git a/src/core/features/courses/tests/behat/basic_usage-310.feature b/src/core/features/courses/tests/behat/basic_usage-310.feature index 21691d4f3..6c4a0e7a6 100755 --- a/src/core/features/courses/tests/behat/basic_usage-310.feature +++ b/src/core/features/courses/tests/behat/basic_usage-310.feature @@ -36,9 +36,8 @@ Feature: Test basic usage of courses in app Scenario: Links to actions in Timeline work for teachers/students # Configure assignment as teacher - Given I entered the course "Course 1" as "teacher1" in the app - When I press "assignment" in the app - And I press "Information" in the app + Given I entered the assign activity "assignment" on course "Course 1" as "teacher1" in the app + When I press "Information" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" diff --git a/src/core/features/courses/tests/behat/basic_usage.feature b/src/core/features/courses/tests/behat/basic_usage.feature index c76f34d9c..46968acf9 100755 --- a/src/core/features/courses/tests/behat/basic_usage.feature +++ b/src/core/features/courses/tests/behat/basic_usage.feature @@ -101,9 +101,8 @@ Feature: Test basic usage of courses in app # TODO remove LMS UI steps in app tests Scenario: Links to actions in Timeline work for teachers/students # Configure assignment as teacher - Given I entered the course "Course 1" as "teacher1" in the app - When I press "assignment" in the app - And I press "Information" in the app + Given I entered the assign activity "assignment" on course "Course 1" as "teacher1" in the app + When I press "Information" in the app And I press "Open in browser" in the app And I switch to the browser tab opened by the app And I log in as "teacher1" diff --git a/src/tests/behat/navigation_externallinks.feature b/src/tests/behat/navigation_externallinks.feature index 35fcf6564..b68264704 100644 --- a/src/tests/behat/navigation_externallinks.feature +++ b/src/tests/behat/navigation_externallinks.feature @@ -19,9 +19,8 @@ Feature: It opens external links properly. | Test forum | student1 | Forum topic | See moodle.org external link | Scenario: Click an external link - Given I entered the course "Course 1" as "student1" in the app - When I press "Test forum" in the app - And I press "Forum topic" in the app + Given I entered the forum activity "Test forum" on course "Course 1" as "student1" in the app + When I press "Forum topic" in the app And I press "moodle.org external link" in the app Then I should find "You are about to leave the app" in the app From 51158f4323b8b80e69bfb3b12a18b167cb9d11cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 11 May 2022 16:25:26 +0200 Subject: [PATCH 217/220] MOBILE-4061 core: Fix header not found when navigating from custom URL --- src/core/components/navbar-buttons/navbar-buttons.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/components/navbar-buttons/navbar-buttons.ts b/src/core/components/navbar-buttons/navbar-buttons.ts index 77878e67c..88dd4dcd0 100644 --- a/src/core/components/navbar-buttons/navbar-buttons.ts +++ b/src/core/components/navbar-buttons/navbar-buttons.ts @@ -208,10 +208,17 @@ export class CoreNavBarButtonsComponent implements OnInit, OnDestroy { await content.componentOnReady(); } - parentPage = parentPage.parentElement.closest('.ion-page'); + parentPage = parentPage.parentElement.closest('.ion-page, .ion-page-hidden, .ion-page-invisible'); // Check if the page has a header. If it doesn't, search the next parent page. - const header = parentPage?.querySelector(':scope > ion-header'); + let header = parentPage?.querySelector(':scope > ion-header'); + + if (header && getComputedStyle(header).display !== 'none') { + return header; + } + + // Find using content if any. + header = content?.parentElement?.querySelector(':scope > ion-header'); if (header && getComputedStyle(header).display !== 'none') { return header; From 0cb07d839daec18d30c48d78dfaa886158b6a13c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 12 May 2022 10:54:32 +0200 Subject: [PATCH 218/220] MOBILE-4061 behat: Fix behat labels --- src/addons/messages/tests/behat/basic_usage.feature | 2 +- src/addons/messages/tests/behat/navigation.feature | 2 +- src/addons/messages/tests/behat/settings.feature | 2 +- src/core/features/course/tests/behat/basic_usage-311.feature | 2 +- src/core/features/course/tests/behat/basic_usage.feature | 2 +- src/core/features/courses/tests/behat/basic_usage-310.feature | 2 +- src/core/features/courses/tests/behat/basic_usage-311.feature | 2 +- src/core/features/courses/tests/behat/basic_usage.feature | 2 +- src/core/features/login/tests/behat/basic_usage.feature | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/addons/messages/tests/behat/basic_usage.feature b/src/addons/messages/tests/behat/basic_usage.feature index 9ef3ed120..86a4f89cb 100755 --- a/src/addons/messages/tests/behat/basic_usage.feature +++ b/src/addons/messages/tests/behat/basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_messages @app @javascript +@core @core_message @app @javascript Feature: Test basic usage of messages in app In order to participate with messages while using the mobile app As a student diff --git a/src/addons/messages/tests/behat/navigation.feature b/src/addons/messages/tests/behat/navigation.feature index 2fd1e3685..633d564f2 100644 --- a/src/addons/messages/tests/behat/navigation.feature +++ b/src/addons/messages/tests/behat/navigation.feature @@ -1,4 +1,4 @@ -@mod @mod_messages @app @javascript +@core @core_message @app @javascript Feature: Test messages navigation in the app Background: diff --git a/src/addons/messages/tests/behat/settings.feature b/src/addons/messages/tests/behat/settings.feature index ca2499b48..ba3fb76f0 100644 --- a/src/addons/messages/tests/behat/settings.feature +++ b/src/addons/messages/tests/behat/settings.feature @@ -1,4 +1,4 @@ -@mod @mod_messages @app @javascript +@core @core_message @app @javascript Feature: Test messages settings Background: diff --git a/src/core/features/course/tests/behat/basic_usage-311.feature b/src/core/features/course/tests/behat/basic_usage-311.feature index 9622a2904..dd88d8151 100755 --- a/src/core/features/course/tests/behat/basic_usage-311.feature +++ b/src/core/features/course/tests/behat/basic_usage-311.feature @@ -1,4 +1,4 @@ -@mod @mod_course @app @javascript @lms_upto3.11 +@core @core_course @app @javascript @lms_upto3.11 Feature: Test basic usage of one course in app In order to participate in one course while using the mobile app As a student diff --git a/src/core/features/course/tests/behat/basic_usage.feature b/src/core/features/course/tests/behat/basic_usage.feature index c849ed61d..9be9bcf6d 100755 --- a/src/core/features/course/tests/behat/basic_usage.feature +++ b/src/core/features/course/tests/behat/basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_course @app @javascript +@core @core_course @app @javascript Feature: Test basic usage of one course in app In order to participate in one course while using the mobile app As a student diff --git a/src/core/features/courses/tests/behat/basic_usage-310.feature b/src/core/features/courses/tests/behat/basic_usage-310.feature index 6c4a0e7a6..8b28fede8 100755 --- a/src/core/features/courses/tests/behat/basic_usage-310.feature +++ b/src/core/features/courses/tests/behat/basic_usage-310.feature @@ -1,4 +1,4 @@ -@mod @mod_courses @app @javascript @lms_upto3.10 +@core @core_course @app @javascript @lms_upto3.10 Feature: Test basic usage of courses in app In order to participate in the courses while using the mobile app As a student diff --git a/src/core/features/courses/tests/behat/basic_usage-311.feature b/src/core/features/courses/tests/behat/basic_usage-311.feature index 3b0a4a52c..91589822b 100755 --- a/src/core/features/courses/tests/behat/basic_usage-311.feature +++ b/src/core/features/courses/tests/behat/basic_usage-311.feature @@ -1,4 +1,4 @@ -@mod @mod_courses @app @javascript @lms_upto3.11 +@core @core_course @app @javascript @lms_upto3.11 Feature: Test basic usage of courses in app In order to participate in the courses while using the mobile app As a student diff --git a/src/core/features/courses/tests/behat/basic_usage.feature b/src/core/features/courses/tests/behat/basic_usage.feature index 46968acf9..14b58707b 100755 --- a/src/core/features/courses/tests/behat/basic_usage.feature +++ b/src/core/features/courses/tests/behat/basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_courses @app @javascript +@core @core_course @app @javascript Feature: Test basic usage of courses in app In order to participate in the courses while using the mobile app As a student diff --git a/src/core/features/login/tests/behat/basic_usage.feature b/src/core/features/login/tests/behat/basic_usage.feature index 23f314947..a558d1f74 100755 --- a/src/core/features/login/tests/behat/basic_usage.feature +++ b/src/core/features/login/tests/behat/basic_usage.feature @@ -1,4 +1,4 @@ -@mod @mod_login @app @javascript +@auth @core_auth @app @javascript Feature: Test basic usage of login in app I need basic login functionality to work From 2044576281611c24dd6e69761f9c61dd1bef3f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 12 May 2022 15:31:08 +0200 Subject: [PATCH 219/220] MOBILE-4061 behat: Improve step selectors --- .../tests/behat/behat_app.php | 189 +++++++++++------- .../messages/tests/behat/basic_usage.feature | 5 +- .../usertours/tests/behat/usertours.feature | 2 +- 3 files changed, 124 insertions(+), 72 deletions(-) diff --git a/local-moodleappbehat/tests/behat/behat_app.php b/local-moodleappbehat/tests/behat/behat_app.php index 16f3a52a6..646f887d9 100644 --- a/local-moodleappbehat/tests/behat/behat_app.php +++ b/local-moodleappbehat/tests/behat/behat_app.php @@ -113,36 +113,50 @@ class behat_app extends behat_base { } /** - * Opens the Moodle App in the browser and introduces the enters the site. + * Opens the Moodle App in the browser and optionally logs in. * - * @Given /^I enter the app$/ + * @When I enter the app + * @Given I entered the app as :username * @throws DriverException Issue with configuration or feature file * @throws dml_exception Problem with Moodle setup * @throws ExpectationException Problem with resizing window */ - public function i_enter_the_app() { + public function i_enter_the_app(string $username = null) { $this->i_launch_the_app(); - $this->enter_site(); + + if (!is_null($username)) { + $this->open_moodleapp_custom_login_url($username); + + return; + } + + if (!$this->is_in_login_page()) { + // Already in the site. + return; + } + + global $CFG; + + $this->i_set_the_field_in_the_app('Your site', $CFG->behat_wwwroot); + $this->i_press_in_the_app('"Connect to your site"'); + $this->wait_for_pending_js(); } /** - * Opens the Moodle App in the browser logged in as a user. - * - * @Given /^I enter(ed)? the app as "(.+)"$/ - * @throws DriverException Issue with configuration or feature file - * @throws dml_exception Problem with Moodle setup - * @throws ExpectationException Problem with resizing window + * Check whether the current page is the login form. */ - public function i_entered_the_app_as(bool $unused, string $username) { - $this->i_launch_the_app(); + protected function is_in_login_page(): bool { + $page = $this->getSession()->getPage(); + $logininput = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); - $this->open_moodleapp_custom_login_url($username); + return !is_null($logininput); } /** * Opens the Moodle App in the browser. * - * @Given /^I launch the app( runtime)?$/ + * @When I launch the app :runtime + * @When I launch the app * @throws DriverException Issue with configuration or feature file * @throws dml_exception Problem with Moodle setup * @throws ExpectationException Problem with resizing window @@ -158,7 +172,7 @@ class behat_app extends behat_base { } /** - * @Then /^I wait the app to restart$/ + * @Then I wait the app to restart */ public function i_wait_the_app_to_restart() { // Wait window to reload. @@ -180,9 +194,6 @@ class behat_app extends behat_base { * Finds elements in the app. * * @Then /^I should( not)? find (".+")( inside the .+)? in the app$/ - * @param bool $not - * @param string $locator - * @param string $containerName */ public function i_find_in_the_app(bool $not, string $locator, string $containerName = '') { $locator = $this->parse_element_locator($locator); @@ -558,19 +569,6 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } - protected function enter_site() { - if (!$this->is_in_login_page()) { - // Already in the site. - return; - } - - global $CFG; - - $this->i_set_the_field_in_the_app('Your site', $CFG->behat_wwwroot); - $this->i_press_in_the_app('"Connect to your site"'); - $this->wait_for_pending_js(); - } - /** * Carries out the login steps for the app, assuming the user is on the app login page. Called * from behat_auth.php. @@ -591,7 +589,7 @@ class behat_app extends behat_base { function($context, $args) { $mainmenu = $context->getSession()->getPage()->find('xpath', '//page-core-mainmenu'); if ($mainmenu) { - return 'mainpage'; + return true; } throw new DriverException('Moodle App main page not loaded after login'); }, false, 30); @@ -601,16 +599,15 @@ class behat_app extends behat_base { } /** - * User enters a course in the app. + * Shortcut to let the user enter a course in the app. * - * @Given /^I enter(ed)? the course "([^"]+)"(?: as "([^"]+)")? in the app$/ + * @Given I entered the course :coursename as :username in the app + * @Given I entered the course :coursename in the app * @param string $coursename Course name * @throws DriverException If the button push doesn't work */ - public function i_enter_the_course_in_the_app(bool $unused, string $coursename, ?string $username = null) { - global $DB; - - $courseid = $DB->get_field('course', 'id', [ 'fullname' => $coursename]); + public function i_entered_the_course_in_the_app(string $coursename, ?string $username = null) { + $courseid = $this->get_course_id($coursename); if (!$courseid) { throw new DriverException("Course '$coursename' not found"); } @@ -625,30 +622,50 @@ class behat_app extends behat_base { } /** - * User enters an activity in a course in the app. + * User enters a course in the app. * - * @Given /^I enter(ed)? the (.+) activity "([^"]+)" on course "([^"]+)"(?: as "([^"]+)")? in the app$/ + * @Given I enter the course :coursename in the app * @param string $coursename Course name * @throws DriverException If the button push doesn't work */ - public function i_enter_the_activity_in_the_app(bool $unused, string $activity, string $activityname, string $coursename, ?string $username = null) { - global $DB; - - $courseid = $DB->get_field('course', 'id', [ 'fullname' => $coursename]); - if (!$courseid) { - throw new DriverException("Course '$coursename' not found"); + public function i_enter_the_course_in_the_app(string $coursename, ?string $username = null) { + if (!is_null($username)) { + $this->i_enter_the_app(); + $this->login($username); } - if ($activity === 'assignment') { - $activity = 'assign'; + $mycoursesfound = $this->evaluate_script("return window.behat.find({ text: 'My courses', selector: 'ion-tab-button'});"); + + if ($mycoursesfound !== 'OK') { + // My courses not present enter from Dashboard. + $this->i_press_in_the_app('"Home" "ion-tab-button"'); + $this->i_press_in_the_app('"Dashboard"'); + $this->i_press_in_the_app('"'.$coursename.'" near "Course overview"'); + + $this->wait_for_pending_js(); + + return; } - $module = $DB->get_record($activity, ['name' => $activityname, 'course' => $courseid ]); - if (!$module) { + $this->i_press_in_the_app('"My courses" "ion-tab-button"'); + $this->i_press_in_the_app('"'.$coursename.'"'); + + $this->wait_for_pending_js(); + } + + /** + * User enters an activity in a course in the app. + * + * @Given I entered the :activity activity :activityname on course :course as :username in the app + * @Given I entered the :activity activity :activityname on course :course in the app + * @throws DriverException If the button push doesn't work + */ + public function i_enter_the_activity_in_the_app(string $activity, string $activityname, string $coursename, ?string $username = null) { + $cm = $this->get_cm_by_activity_name_and_course($activity, $activityname, $coursename); + if (!$cm) { throw new DriverException("'$activityname' activity '$activityname' not found"); } - $cm = get_coursemodule_from_instance($activity, $module->id); $pageurl = "/mod/$activity/view.php?id={$cm->id}"; if ($username) { @@ -663,7 +680,7 @@ class behat_app extends behat_base { /** * Presses standard buttons in the app. * - * @Given /^I press the (back|more menu|page menu|user menu|main menu) button in the app$/ + * @When /^I press the (back|more menu|page menu|user menu|main menu) button in the app$/ * @param string $button Button type * @throws DriverException If the button push doesn't work */ @@ -684,7 +701,7 @@ class behat_app extends behat_base { /** * Receives push notifications. * - * @Given /^I receive a push notification in the app for:$/ + * @When /^I receive a push notification in the app for:$/ * @param TableNode $data */ public function i_receive_a_push_notification(TableNode $data) { @@ -788,7 +805,7 @@ class behat_app extends behat_base { /** * Closes a popup by clicking on the 'backdrop' behind it. * - * @Given /^I close the popup in the app$/ + * @When I close the popup in the app * @throws DriverException If there isn't a popup to close */ public function i_close_the_popup_in_the_app() { @@ -895,16 +912,6 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } - /** - * Check whether the current page is the login form. - */ - protected function is_in_login_page(): bool { - $page = $this->getSession()->getPage(); - $logininput = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); - - return !is_null($logininput); - } - /** * Sets a field to the given text value in the app. * @@ -966,7 +973,7 @@ class behat_app extends behat_base { /** * Check that the app opened a new browser tab. * - * @Given /^the app should( not)? have opened a browser tab(?: with url "(?P[^"]+)")?$/ + * @Then /^the app should( not)? have opened a browser tab(?: with url "(?P[^"]+)")?$/ * @param bool $not * @param string $urlpattern */ @@ -1009,7 +1016,7 @@ class behat_app extends behat_base { * * This assumes the app opened a new tab. * - * @Given /^I switch to the browser tab opened by the app$/ + * @Given I switch to the browser tab opened by the app * @throws DriverException If there aren't exactly 2 tabs open */ public function i_switch_to_the_browser_tab_opened_by_the_app() { @@ -1023,7 +1030,7 @@ class behat_app extends behat_base { /** * Force cron tasks instead of waiting for the next scheduled execution. * - * @When /^I run cron tasks in the app$/ + * @When I run cron tasks in the app */ public function i_run_cron_tasks_in_the_app() { $session = $this->getSession(); @@ -1050,7 +1057,7 @@ class behat_app extends behat_base { /** * Wait until loading has finished. * - * @When /^I wait loading to finish in the app$/ + * @When I wait loading to finish in the app */ public function i_wait_loading_to_finish_in_the_app() { $session = $this->getSession(); @@ -1082,7 +1089,7 @@ class behat_app extends behat_base { * * This assumes it was opened by the app and you will now get back to the app. * - * @Given /^I close the browser tab opened by the app$/ + * @Given I close the browser tab opened by the app * @throws DriverException If there aren't exactly 2 tabs open */ public function i_close_the_browser_tab_opened_by_the_app() { @@ -1339,4 +1346,48 @@ class behat_app extends behat_base { return !empty($mobilesettings->forcedurlscheme) ? $mobilesettings->forcedurlscheme : 'moodlemobile'; } + /** + * Get a coursemodule from an activity name or idnumber with course. + * + * @param string $activity + * @param string $identifier + * @param string $coursename + * @return cm_info + */ + protected function get_cm_by_activity_name_and_course(string $activity, string $identifier, string $coursename): cm_info { + global $DB; + + $courseid = $this->get_course_id($coursename); + if (!$courseid) { + throw new DriverException("Course '$coursename' not found"); + } + + if ($activity === 'assignment') { + $activity = 'assign'; + } + + $cmtable = new \core\dml\table('course_modules', 'cm', 'cm'); + $cmfrom = $cmtable->get_from_sql(); + + $acttable = new \core\dml\table($activity, 'a', 'a'); + $actselect = $acttable->get_field_select(); + $actfrom = $acttable->get_from_sql(); + + $sql = <<get_record_sql($sql, [ + 'modname' => $activity, + 'idnumber' => $identifier, + 'name' => $identifier, + 'courseid' => $courseid, + ], MUST_EXIST); + + return get_fast_modinfo($courseid)->get_cm($result->cmid); + } } diff --git a/src/addons/messages/tests/behat/basic_usage.feature b/src/addons/messages/tests/behat/basic_usage.feature index 86a4f89cb..c84ed18fd 100755 --- a/src/addons/messages/tests/behat/basic_usage.feature +++ b/src/addons/messages/tests/behat/basic_usage.feature @@ -202,8 +202,9 @@ Feature: Test basic usage of messages in app When I switch offline mode to "false" And I run cron tasks in the app - And I enter the app as "student1" - And I press "Messages" in the app + + Given I entered the app as "student1" + When I press "Messages" in the app And I press "Teacher teacher" in the app Then I should find "heeey student" in the app And I should find "byee" in the app diff --git a/src/core/features/usertours/tests/behat/usertours.feature b/src/core/features/usertours/tests/behat/usertours.feature index 7a24915de..4139db45a 100644 --- a/src/core/features/usertours/tests/behat/usertours.feature +++ b/src/core/features/usertours/tests/behat/usertours.feature @@ -29,7 +29,7 @@ Feature: User Tours work properly. Then I should not find "Expand to explore" in the app And I should not find "Explore your personal area" in the app - When I enter the course "Course 1" in the app + Given I entered the course "Course 1" in the app Then I should find "Find your way around" in the app When I press "Got it" in the app From 79bb346debe86737b7a9b05195d7a448d9325fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 12 May 2022 10:55:15 +0200 Subject: [PATCH 220/220] MOBILE-4061 behat: Split behat_app: steps and helper functions --- .../tests/behat/behat_app.php | 597 +---------------- .../tests/behat/behat_app_helper.php | 619 ++++++++++++++++++ 2 files changed, 621 insertions(+), 595 deletions(-) create mode 100644 local-moodleappbehat/tests/behat/behat_app_helper.php diff --git a/local-moodleappbehat/tests/behat/behat_app.php b/local-moodleappbehat/tests/behat/behat_app.php index 646f887d9..524ed7e3b 100644 --- a/local-moodleappbehat/tests/behat/behat_app.php +++ b/local-moodleappbehat/tests/behat/behat_app.php @@ -14,40 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Moodle App steps definitions. - * - * @package core - * @category test - * @copyright 2018 The Open University - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. require_once(__DIR__ . '/../../../../lib/behat/behat_base.php'); +require_once(__DIR__ . '/behat_app_helper.php'); use Behat\Gherkin\Node\TableNode; use Behat\Mink\Exception\DriverException; use Behat\Mink\Exception\ExpectationException; -/** - * Behat app listener. - */ -interface behat_app_listener { - - /** - * Called when the app is loaded. - */ - function on_app_load(): void; - - /** - * Called before the app is unloaded. - */ - function on_app_unload(): void; - -} - /** * Moodle App steps definitions. * @@ -56,62 +31,16 @@ interface behat_app_listener { * @copyright 2018 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class behat_app extends behat_base { - /** @var stdClass Object with data about launched Ionic instance (if any) */ - protected static $ionicrunning = null; - - /** @var array */ - protected static $listeners = []; +class behat_app extends behat_app_helper { /** @var string URL for running Ionic server */ protected $ionicurl = ''; - /** @var bool Whether the app is running or not */ - protected $apprunning = false; - /** @var array Config overrides */ protected $appconfig = ['disableUserTours' => true]; protected $windowsize = '360x720'; - /** - * Register listener. - * - * @param behat_app_listener $listener Listener. - * @return Closure Unregister function. - */ - public static function listen(behat_app_listener $listener): Closure { - self::$listeners[] = $listener; - - return function () use ($listener) { - $index = array_search($listener, self::$listeners); - - if ($index !== false) { - array_splice(self::$listeners, $index, 1); - } - }; - } - - /** - * Checks if the current OS is Windows, from the point of view of task-executing-and-killing. - * - * @return bool True if Windows - */ - protected static function is_windows() : bool { - return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; - } - - /** - * Called from behat_hooks when a new scenario starts, if it has the app tag. - * - * This updates Moodle configuration and starts Ionic running, if it isn't already. - */ - public function start_scenario() { - $this->check_behat_setup(); - $this->fix_moodle_setup(); - $this->ionicurl = $this->start_or_reuse_ionic(); - } - /** * Opens the Moodle App in the browser and optionally logs in. * @@ -320,255 +249,6 @@ class behat_app extends behat_base { $this->wait_for_pending_js(); } - /** - * Checks the Behat setup - tags and configuration. - * - * @throws DriverException - */ - protected function check_behat_setup() { - global $CFG; - - // Check JavaScript is enabled. - if (!$this->running_javascript()) { - throw new DriverException('The app requires JavaScript.'); - } - - // Check the config settings are defined. - if (empty($CFG->behat_ionic_wwwroot) && empty($CFG->behat_ionic_dirroot)) { - throw new DriverException('$CFG->behat_ionic_wwwroot or $CFG->behat_ionic_dirroot must be defined.'); - } - } - - /** - * Fixes the Moodle admin settings to allow Moodle App use (if not already correct). - * - * @throws dml_exception If there is any problem changing Moodle settings - */ - protected function fix_moodle_setup() { - global $CFG, $DB; - - // Configure Moodle settings to enable app web services. - if (!$CFG->enablewebservices) { - set_config('enablewebservices', 1); - } - if (!$CFG->enablemobilewebservice) { - set_config('enablemobilewebservice', 1); - } - - // Add 'Create token' and 'Use REST webservice' permissions to authenticated user role. - $userroleid = $DB->get_field('role', 'id', ['shortname' => 'user']); - $systemcontext = \context_system::instance(); - role_change_permission($userroleid, $systemcontext, 'moodle/webservice:createtoken', CAP_ALLOW); - role_change_permission($userroleid, $systemcontext, 'webservice/rest:use', CAP_ALLOW); - - // Check the value of the 'webserviceprotocols' config option. Due to weird behaviour - // in Behat with regard to config variables that aren't defined in a settings.php, the - // value in $CFG here may reflect a previous run, so get it direct from the database - // instead. - $field = $DB->get_field('config', 'value', ['name' => 'webserviceprotocols'], IGNORE_MISSING); - if (empty($field)) { - $protocols = []; - } else { - $protocols = explode(',', $field); - } - if (!in_array('rest', $protocols)) { - $protocols[] = 'rest'; - set_config('webserviceprotocols', implode(',', $protocols)); - } - - // Enable mobile service. - require_once($CFG->dirroot . '/webservice/lib.php'); - $webservicemanager = new webservice(); - $service = $webservicemanager->get_external_service_by_shortname(MOODLE_OFFICIAL_MOBILE_SERVICE, MUST_EXIST); - - if (!$service->enabled) { - $service->enabled = 1; - $webservicemanager->update_external_service($service); - } - } - - /** - * Starts an Ionic server if necessary, or uses an existing one. - * - * @return string URL to Ionic server - * @throws DriverException If there's a system error starting Ionic - */ - protected function start_or_reuse_ionic() { - global $CFG; - - if (empty($CFG->behat_ionic_dirroot) && !empty($CFG->behat_ionic_wwwroot)) { - // Use supplied Ionic server which should already be running. - $url = $CFG->behat_ionic_wwwroot; - } else if (self::$ionicrunning) { - // Use existing Ionic instance launched previously. - $url = self::$ionicrunning->url; - } else { - // Open Ionic process in relevant path. - $path = realpath($CFG->behat_ionic_dirroot); - $stderrfile = $CFG->dataroot . '/behat/ionic-stderr.log'; - $prefix = ''; - // Except on Windows, use 'exec' so that we get the pid of the actual Node process - // and not the shell it uses to execute. You can't do exec on Windows; there is a - // bypass_shell option but it is not the same thing and isn't usable here. - if (!self::is_windows()) { - $prefix = 'exec '; - } - $process = proc_open($prefix . 'ionic serve --no-interactive --no-open', - [['pipe', 'r'], ['pipe', 'w'], ['file', $stderrfile, 'w']], $pipes, $path); - if ($process === false) { - throw new DriverException('Error starting Ionic process'); - } - fclose($pipes[0]); - - // Get pid - we will need this to kill the process. - $status = proc_get_status($process); - $pid = $status['pid']; - - // Read data from stdout until the server comes online. - // Note: On Windows it is impossible to read simultaneously from stderr and stdout - // because stream_select and non-blocking I/O don't work on process pipes, so that is - // why stderr was redirected to a file instead. Also, this code is simpler. - $url = null; - $stdoutlog = ''; - while (true) { - $line = fgets($pipes[1], 4096); - if ($line === false) { - break; - } - - $stdoutlog .= $line; - - if (preg_match('~^\s*Local: (http\S*)~', $line, $matches)) { - $url = $matches[1]; - break; - } - } - - // If it failed, close the pipes and the process. - if (!$url) { - fclose($pipes[1]); - proc_close($process); - $logpath = $CFG->dataroot . '/behat/ionic-start.log'; - $stderrlog = file_get_contents($stderrfile); - @unlink($stderrfile); - file_put_contents($logpath, - "Ionic startup log from " . date('c') . - "\n\n----STDOUT----\n$stdoutlog\n\n----STDERR----\n$stderrlog"); - throw new DriverException('Unable to start Ionic. See ' . $logpath); - } - - // Remember the URL, so we can reuse it next time, and other details so we can kill - // the process. - self::$ionicrunning = (object)['url' => $url, 'process' => $process, 'pipes' => $pipes, - 'pid' => $pid]; - $url = self::$ionicrunning->url; - } - return $url; - } - - /** - * Closes Ionic (if it was started) at end of test suite. - * - * @AfterSuite - */ - public static function close_ionic() { - if (self::$ionicrunning) { - fclose(self::$ionicrunning->pipes[1]); - - if (self::is_windows()) { - // Using proc_terminate here does not work. It terminates the process but not any - // other processes it might have launched. Instead, we need to use an OS-specific - // mechanism to kill the process and children based on its pid. - exec('taskkill /F /T /PID ' . self::$ionicrunning->pid); - } else { - // On Unix this actually works, although only due to the 'exec' command inserted - // above. - proc_terminate(self::$ionicrunning->process); - } - self::$ionicrunning = null; - } - } - - /** - * Goes to the app page and then sets up some initial JavaScript so we can use it. - * - * @param string $url App URL - * @throws DriverException If the app fails to load properly - */ - protected function prepare_browser(array $options = []) { - $restart = $options['restart'] ?? true; - - if ($restart) { - if ($this->apprunning) { - $this->notify_unload(); - } - - // Restart the browser and set its size. - $this->getSession()->restart(); - $this->resize_window($this->windowsize, true); - - if (empty($this->ionicurl)) { - $this->ionicurl = $this->start_or_reuse_ionic(); - } - - // Visit the Ionic URL. - $this->getSession()->visit($this->ionicurl); - $this->notify_load(); - - $this->apprunning = true; - } - - // Wait the application to load. - $this->spin(function($context) { - $title = $context->getSession()->getPage()->find('xpath', '//title'); - - if ($title) { - $text = $title->getHtml(); - - if ($text === 'Moodle App') { - return true; - } - } - - throw new DriverException('Moodle App not found in browser'); - }, false, 60); - - try { - // Init Behat JavaScript runtime. - - $initOptions = new StdClass(); - $initOptions->skipOnBoarding = $options['skiponboarding'] ?? true; - $initOptions->configOverrides = $this->appconfig; - - $this->execute_script('window.behatInit(' . json_encode($initOptions) . ');'); - } catch (Exception $error) { - throw new DriverException('Moodle App not running or not running on Automated mode.'); - } - - if ($restart) { - // Assert initial page. - $this->spin(function($context) { - $page = $context->getSession()->getPage(); - $element = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); - - if ($element) { - // Login screen found. - return true; - } - - if ($page->find('xpath', '//page-core-mainmenu')) { - // Main menu found. - return true; - } - - throw new DriverException('Moodle App not launched properly'); - }, false, 60); - } - - // Continue only after JS finishes. - $this->wait_for_pending_js(); - } - /** * Carries out the login steps for the app, assuming the user is on the app login page. Called * from behat_auth.php. @@ -1117,277 +797,4 @@ class behat_app extends behat_base { $this->execute_script("appProvider.setForceOffline($offline);"); } - /** - * Parse an element locator string. - * - * @param string $text Element locator string. - * @return JSON of the locator. - */ - public function parse_element_locator(string $text): string { - preg_match( - '/^"((?:[^"]|\\")*?)"(?: "([^"]*?)")?(?: (near|within) "((?:[^"]|\\")*?)"(?: "([^"]*?)")?)?$/', - $text, - $matches - ); - - $locator = [ - 'text' => str_replace('\\"', '"', $matches[1]), - 'selector' => $matches[2] ?? null, - ]; - - if (!empty($matches[3])) { - $locator[$matches[3]] = (object) [ - 'text' => str_replace('\\"', '"', $matches[4]), - 'selector' => $matches[5] ?? null, - ]; - } - - return json_encode((object) $locator); - } - - /** - * Replaces $WWWROOT for the url of the Moodle site. - * - * @Transform /^(.*\$WWWROOT.*)$/ - * @param string $text Text. - * @return string - */ - public function replace_wwwroot($text) { - global $CFG; - - return str_replace('$WWWROOT', $CFG->behat_wwwroot, $text); - } - - /** - * Replace arguments with the format "${activity:field}" from a string, where "activity" is - * the idnumber of an activity and "field" is the activity's field to get replacement from. - * - * At the moment, the only field supported is "cmid", the id of the course module for this activity. - * - * @param string $text Original text. - * @return string Text with arguments replaced. - */ - protected function replace_arguments(string $text): string { - global $DB; - - preg_match_all("/\\$\\{([^:}]+):([^}]+)\\}/", $text, $matches); - - foreach ($matches[0] as $index => $match) { - switch ($matches[2][$index]) { - case 'cmid': - $coursemodule = $DB->get_record('course_modules', ['idnumber' => $matches[1][$index]]); - $text = str_replace($match, $coursemodule->id, $text); - - break; - } - } - - return $text; - } - - /** - * Notify to listeners that the app was just loaded. - */ - private function notify_load(): void { - foreach (self::$listeners as $listener) { - $listener->on_app_load(); - } - } - - /** - * Notify to listeners that the app is about to be unloaded. - */ - private function notify_unload(): void { - foreach (self::$listeners as $listener) { - $listener->on_app_unload(); - } - } - - /** - * Evaluate a script that returns a Promise. - * - * @param string $script - * @return mixed Resolved promise result. - */ - private function evaluate_async_script(string $script) { - $script = preg_replace('/^return\s+/', '', $script); - $script = preg_replace('/;$/', '', $script); - $start = microtime(true); - $promisevariable = 'PROMISE_RESULT_' . time(); - $timeout = self::get_timeout(); - - $this->evaluate_script("Promise.resolve($script) - .then(result => window.$promisevariable = result) - .catch(error => window.$promisevariable = 'Async code rejected: ' + error?.message);"); - - do { - if (microtime(true) - $start > $timeout) { - throw new DriverException("Async script not resolved after $timeout seconds"); - } - - usleep(100000); - } while (!$this->evaluate_script("return '$promisevariable' in window;")); - - $result = $this->evaluate_script("return window.$promisevariable;"); - - $this->evaluate_script("delete window.$promisevariable;"); - - return $result; - } - - - /** - * Trigger Angular change detection. - */ - private function trigger_angular_change_detection() { - $this->getSession()->executeScript('ngZone.run(() => {});'); - } - - /** - * Opens a custom URL for automatic login and redirect from the Moodle App (and waits to finish.) - * - * @param string $username Of the user that needs to be logged in. - * @param string $path To redirect the user. - * @param string $successXPath If a path is declared, the XPath of the element to lookat after redirect. - */ - private function open_moodleapp_custom_login_url($username, $path = '', string $successXPath = '') { - global $CFG, $DB; - - require_once($CFG->libdir.'/externallib.php'); - require_once($CFG->libdir.'/moodlelib.php'); - - // Ensure the user exists. - $userid = $DB->get_field('user', 'id', [ 'username' => $username ]); - if (!$userid) { - throw new DriverException("User '$username' not found"); - } - - // Get or create the user token. - $service = $DB->get_record('external_services', ['shortname' => 'moodle_mobile_app']); - - $token_params = [ - 'userid' => $userid, - 'externalserviceid' => $service->id, - ]; - $usertoken = $DB->get_record('external_tokens', $token_params); - if (!$usertoken) { - $context = context_system::instance(); - $token = external_generate_token(EXTERNAL_TOKEN_PERMANENT, $service, $userid, $context); - $token_params['token'] = $token; - $privatetoken = $DB->get_field('external_tokens', 'privatetoken', $token_params); - } else { - $token = $usertoken->token; - $privatetoken = $usertoken->privatetoken; - } - - // Generate custom URL. - $parsed_url = parse_url($CFG->behat_wwwroot); - $domain = $parsed_url['host']; - $url = $this->get_mobile_url_scheme() . "://$username@$domain?token=$token&privatetoken=$privatetoken"; - - if (!empty($path)) { - $url .= '&redirect='.urlencode($CFG->behat_wwwroot.$path); - } else { - $successXPath = '//page-core-mainmenu'; - } - - $this->handle_url_and_wait_page_to_load($url, $successXPath); - } - - /** - * Opens a custom URL on the Moodle App (and waits to finish.) - * - * @param string $path To navigate. - * @param string $successXPath The XPath of the element to lookat after navigation. - */ - private function open_moodleapp_custom_url(string $path, string $successXPath = '') { - global $CFG; - - $urlscheme = $this->get_mobile_url_scheme(); - $url = "$urlscheme://link=" . urlencode($CFG->behat_wwwroot.$path); - - $this->handle_url_and_wait_page_to_load($url); - } - - /** - * Handles the custom URL on the Moodle App (and waits to finish.) - * - * @param string $customurl To navigate. - * @param string $successXPath The XPath of the element to lookat after navigation. - */ - private function handle_url_and_wait_page_to_load(string $customurl, string $successXPath = '') { - // Instead of using evaluate_async_script, we wait for the path to load. - $this->evaluate_script("return window.behat.handleCustomURL('$customurl')"); - - $this->wait_for_pending_js(); - - if (!empty($successXPath)) { - // Wait until the page appears. - $this->spin( - function($context, $args) use ($successXPath) { - $found = $context->getSession()->getPage()->find('xpath', $successXPath); - if ($found) { - return true; - } - throw new DriverException('Moodle App custom URL page not loaded'); - }, false, 30); - } - - // Wait for JS to finish as well. - $this->wait_for_pending_js(); - } - - /** - * Returns the current mobile url scheme of the site. - */ - private function get_mobile_url_scheme() { - $mobilesettings = get_config('tool_mobile'); - - return !empty($mobilesettings->forcedurlscheme) ? $mobilesettings->forcedurlscheme : 'moodlemobile'; - } - - /** - * Get a coursemodule from an activity name or idnumber with course. - * - * @param string $activity - * @param string $identifier - * @param string $coursename - * @return cm_info - */ - protected function get_cm_by_activity_name_and_course(string $activity, string $identifier, string $coursename): cm_info { - global $DB; - - $courseid = $this->get_course_id($coursename); - if (!$courseid) { - throw new DriverException("Course '$coursename' not found"); - } - - if ($activity === 'assignment') { - $activity = 'assign'; - } - - $cmtable = new \core\dml\table('course_modules', 'cm', 'cm'); - $cmfrom = $cmtable->get_from_sql(); - - $acttable = new \core\dml\table($activity, 'a', 'a'); - $actselect = $acttable->get_field_select(); - $actfrom = $acttable->get_from_sql(); - - $sql = <<get_record_sql($sql, [ - 'modname' => $activity, - 'idnumber' => $identifier, - 'name' => $identifier, - 'courseid' => $courseid, - ], MUST_EXIST); - - return get_fast_modinfo($courseid)->get_cm($result->cmid); - } } diff --git a/local-moodleappbehat/tests/behat/behat_app_helper.php b/local-moodleappbehat/tests/behat/behat_app_helper.php new file mode 100644 index 000000000..fc30cbed3 --- /dev/null +++ b/local-moodleappbehat/tests/behat/behat_app_helper.php @@ -0,0 +1,619 @@ +. + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../../../lib/behat/behat_base.php'); + +use Behat\Mink\Exception\DriverException; + +/** + * Behat app listener. + */ +interface behat_app_listener { + + /** + * Called when the app is loaded. + */ + function on_app_load(): void; + + /** + * Called before the app is unloaded. + */ + function on_app_unload(): void; + +} + +/** + * A trait containing functionality used by the behat app context. + * + * @package core + * @category test + * @copyright 2018 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_app_helper extends behat_base { + + /** @var stdClass Object with data about launched Ionic instance (if any) */ + protected static $ionicrunning = null; + + /** @var array */ + protected static $listeners = []; + + /** @var bool Whether the app is running or not */ + protected $apprunning = false; + + /** + * Register listener. + * + * @param behat_app_listener $listener Listener. + * @return Closure Unregister function. + */ + public static function listen(behat_app_listener $listener): Closure { + self::$listeners[] = $listener; + + return function () use ($listener) { + $index = array_search($listener, self::$listeners); + + if ($index !== false) { + array_splice(self::$listeners, $index, 1); + } + }; + } + + /** + * Checks if the current OS is Windows, from the point of view of task-executing-and-killing. + * + * @return bool True if Windows + */ + protected static function is_windows() : bool { + return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; + } + + /** + * Called from behat_hooks when a new scenario starts, if it has the app tag. + * + * This updates Moodle configuration and starts Ionic running, if it isn't already. + */ + public function start_scenario() { + $this->check_behat_setup(); + $this->fix_moodle_setup(); + $this->ionicurl = $this->start_or_reuse_ionic(); + } + + /** + * Checks the Behat setup - tags and configuration. + * + * @throws DriverException + */ + protected function check_behat_setup() { + global $CFG; + + // Check JavaScript is enabled. + if (!$this->running_javascript()) { + throw new DriverException('The app requires JavaScript.'); + } + + // Check the config settings are defined. + if (empty($CFG->behat_ionic_wwwroot) && empty($CFG->behat_ionic_dirroot)) { + throw new DriverException('$CFG->behat_ionic_wwwroot or $CFG->behat_ionic_dirroot must be defined.'); + } + } + + /** + * Fixes the Moodle admin settings to allow Moodle App use (if not already correct). + * + * @throws dml_exception If there is any problem changing Moodle settings + */ + protected function fix_moodle_setup() { + global $CFG, $DB; + + // Configure Moodle settings to enable app web services. + if (!$CFG->enablewebservices) { + set_config('enablewebservices', 1); + } + if (!$CFG->enablemobilewebservice) { + set_config('enablemobilewebservice', 1); + } + + // Add 'Create token' and 'Use REST webservice' permissions to authenticated user role. + $userroleid = $DB->get_field('role', 'id', ['shortname' => 'user']); + $systemcontext = \context_system::instance(); + role_change_permission($userroleid, $systemcontext, 'moodle/webservice:createtoken', CAP_ALLOW); + role_change_permission($userroleid, $systemcontext, 'webservice/rest:use', CAP_ALLOW); + + // Check the value of the 'webserviceprotocols' config option. Due to weird behaviour + // in Behat with regard to config variables that aren't defined in a settings.php, the + // value in $CFG here may reflect a previous run, so get it direct from the database + // instead. + $field = $DB->get_field('config', 'value', ['name' => 'webserviceprotocols'], IGNORE_MISSING); + if (empty($field)) { + $protocols = []; + } else { + $protocols = explode(',', $field); + } + if (!in_array('rest', $protocols)) { + $protocols[] = 'rest'; + set_config('webserviceprotocols', implode(',', $protocols)); + } + + // Enable mobile service. + require_once($CFG->dirroot . '/webservice/lib.php'); + $webservicemanager = new webservice(); + $service = $webservicemanager->get_external_service_by_shortname(MOODLE_OFFICIAL_MOBILE_SERVICE, MUST_EXIST); + + if (!$service->enabled) { + $service->enabled = 1; + $webservicemanager->update_external_service($service); + } + } + + /** + * Starts an Ionic server if necessary, or uses an existing one. + * + * @return string URL to Ionic server + * @throws DriverException If there's a system error starting Ionic + */ + protected function start_or_reuse_ionic() { + global $CFG; + + if (empty($CFG->behat_ionic_dirroot) && !empty($CFG->behat_ionic_wwwroot)) { + // Use supplied Ionic server which should already be running. + $url = $CFG->behat_ionic_wwwroot; + } else if (self::$ionicrunning) { + // Use existing Ionic instance launched previously. + $url = self::$ionicrunning->url; + } else { + // Open Ionic process in relevant path. + $path = realpath($CFG->behat_ionic_dirroot); + $stderrfile = $CFG->dataroot . '/behat/ionic-stderr.log'; + $prefix = ''; + // Except on Windows, use 'exec' so that we get the pid of the actual Node process + // and not the shell it uses to execute. You can't do exec on Windows; there is a + // bypass_shell option but it is not the same thing and isn't usable here. + if (!self::is_windows()) { + $prefix = 'exec '; + } + $process = proc_open($prefix . 'ionic serve --no-interactive --no-open', + [['pipe', 'r'], ['pipe', 'w'], ['file', $stderrfile, 'w']], $pipes, $path); + if ($process === false) { + throw new DriverException('Error starting Ionic process'); + } + fclose($pipes[0]); + + // Get pid - we will need this to kill the process. + $status = proc_get_status($process); + $pid = $status['pid']; + + // Read data from stdout until the server comes online. + // Note: On Windows it is impossible to read simultaneously from stderr and stdout + // because stream_select and non-blocking I/O don't work on process pipes, so that is + // why stderr was redirected to a file instead. Also, this code is simpler. + $url = null; + $stdoutlog = ''; + while (true) { + $line = fgets($pipes[1], 4096); + if ($line === false) { + break; + } + + $stdoutlog .= $line; + + if (preg_match('~^\s*Local: (http\S*)~', $line, $matches)) { + $url = $matches[1]; + break; + } + } + + // If it failed, close the pipes and the process. + if (!$url) { + fclose($pipes[1]); + proc_close($process); + $logpath = $CFG->dataroot . '/behat/ionic-start.log'; + $stderrlog = file_get_contents($stderrfile); + @unlink($stderrfile); + file_put_contents($logpath, + "Ionic startup log from " . date('c') . + "\n\n----STDOUT----\n$stdoutlog\n\n----STDERR----\n$stderrlog"); + throw new DriverException('Unable to start Ionic. See ' . $logpath); + } + + // Remember the URL, so we can reuse it next time, and other details so we can kill + // the process. + self::$ionicrunning = (object)['url' => $url, 'process' => $process, 'pipes' => $pipes, + 'pid' => $pid]; + $url = self::$ionicrunning->url; + } + return $url; + } + + /** + * Closes Ionic (if it was started) at end of test suite. + * + * @AfterSuite + */ + public static function close_ionic() { + if (self::$ionicrunning) { + fclose(self::$ionicrunning->pipes[1]); + + if (self::is_windows()) { + // Using proc_terminate here does not work. It terminates the process but not any + // other processes it might have launched. Instead, we need to use an OS-specific + // mechanism to kill the process and children based on its pid. + exec('taskkill /F /T /PID ' . self::$ionicrunning->pid); + } else { + // On Unix this actually works, although only due to the 'exec' command inserted + // above. + proc_terminate(self::$ionicrunning->process); + } + self::$ionicrunning = null; + } + } + + /** + * Goes to the app page and then sets up some initial JavaScript so we can use it. + * + * @param string $url App URL + * @throws DriverException If the app fails to load properly + */ + protected function prepare_browser(array $options = []) { + $restart = $options['restart'] ?? true; + + if ($restart) { + if ($this->apprunning) { + $this->notify_unload(); + } + + // Restart the browser and set its size. + $this->getSession()->restart(); + $this->resize_window($this->windowsize, true); + + if (empty($this->ionicurl)) { + $this->ionicurl = $this->start_or_reuse_ionic(); + } + + // Visit the Ionic URL. + $this->getSession()->visit($this->ionicurl); + $this->notify_load(); + + $this->apprunning = true; + } + + // Wait the application to load. + $this->spin(function($context) { + $title = $context->getSession()->getPage()->find('xpath', '//title'); + + if ($title) { + $text = $title->getHtml(); + + if ($text === 'Moodle App') { + return true; + } + } + + throw new DriverException('Moodle App not found in browser'); + }, false, 60); + + try { + // Init Behat JavaScript runtime. + + $initOptions = new StdClass(); + $initOptions->skipOnBoarding = $options['skiponboarding'] ?? true; + $initOptions->configOverrides = $this->appconfig; + + $this->execute_script('window.behatInit(' . json_encode($initOptions) . ');'); + } catch (Exception $error) { + throw new DriverException('Moodle App not running or not running on Automated mode.'); + } + + if ($restart) { + // Assert initial page. + $this->spin(function($context) { + $page = $context->getSession()->getPage(); + $element = $page->find('xpath', '//page-core-login-site//input[@name="url"]'); + + if ($element) { + // Login screen found. + return true; + } + + if ($page->find('xpath', '//page-core-mainmenu')) { + // Main menu found. + return true; + } + + throw new DriverException('Moodle App not launched properly'); + }, false, 60); + } + + // Continue only after JS finishes. + $this->wait_for_pending_js(); + } + + /** + * Parse an element locator string. + * + * @param string $text Element locator string. + * @return JSON of the locator. + */ + public function parse_element_locator(string $text): string { + preg_match( + '/^"((?:[^"]|\\")*?)"(?: "([^"]*?)")?(?: (near|within) "((?:[^"]|\\")*?)"(?: "([^"]*?)")?)?$/', + $text, + $matches + ); + + $locator = [ + 'text' => str_replace('\\"', '"', $matches[1]), + 'selector' => $matches[2] ?? null, + ]; + + if (!empty($matches[3])) { + $locator[$matches[3]] = (object) [ + 'text' => str_replace('\\"', '"', $matches[4]), + 'selector' => $matches[5] ?? null, + ]; + } + + return json_encode((object) $locator); + } + + /** + * Replaces $WWWROOT for the url of the Moodle site. + * + * @Transform /^(.*\$WWWROOT.*)$/ + * @param string $text Text. + * @return string + */ + public function replace_wwwroot($text) { + global $CFG; + + return str_replace('$WWWROOT', $CFG->behat_wwwroot, $text); + } + + /** + * Replace arguments with the format "${activity:field}" from a string, where "activity" is + * the idnumber of an activity and "field" is the activity's field to get replacement from. + * + * At the moment, the only field supported is "cmid", the id of the course module for this activity. + * + * @param string $text Original text. + * @return string Text with arguments replaced. + */ + protected function replace_arguments(string $text): string { + global $DB; + + preg_match_all("/\\$\\{([^:}]+):([^}]+)\\}/", $text, $matches); + + foreach ($matches[0] as $index => $match) { + switch ($matches[2][$index]) { + case 'cmid': + $coursemodule = $DB->get_record('course_modules', ['idnumber' => $matches[1][$index]]); + $text = str_replace($match, $coursemodule->id, $text); + + break; + } + } + + return $text; + } + + /** + * Notify to listeners that the app was just loaded. + */ + protected function notify_load(): void { + foreach (self::$listeners as $listener) { + $listener->on_app_load(); + } + } + + /** + * Notify to listeners that the app is about to be unloaded. + */ + protected function notify_unload(): void { + foreach (self::$listeners as $listener) { + $listener->on_app_unload(); + } + } + + + /** + * Trigger Angular change detection. + */ + protected function trigger_angular_change_detection() { + $this->getSession()->executeScript('ngZone.run(() => {});'); + } + + /** + * Evaluate a script that returns a Promise. + * + * @param string $script + * @return mixed Resolved promise result. + */ + protected function evaluate_async_script(string $script) { + $script = preg_replace('/^return\s+/', '', $script); + $script = preg_replace('/;$/', '', $script); + $start = microtime(true); + $promisevariable = 'PROMISE_RESULT_' . time(); + $timeout = self::get_timeout(); + + $this->evaluate_script("Promise.resolve($script) + .then(result => window.$promisevariable = result) + .catch(error => window.$promisevariable = 'Async code rejected: ' + error?.message);"); + + do { + if (microtime(true) - $start > $timeout) { + throw new DriverException("Async script not resolved after $timeout seconds"); + } + + usleep(100000); + } while (!$this->evaluate_script("return '$promisevariable' in window;")); + + $result = $this->evaluate_script("return window.$promisevariable;"); + + $this->evaluate_script("delete window.$promisevariable;"); + + return $result; + } + + /** + * Opens a custom URL for automatic login and redirect from the Moodle App (and waits to finish.) + * + * @param string $username Of the user that needs to be logged in. + * @param string $path To redirect the user. + * @param string $successXPath If a path is declared, the XPath of the element to lookat after redirect. + */ + protected function open_moodleapp_custom_login_url($username, $path = '', string $successXPath = '') { + global $CFG, $DB; + + require_once($CFG->libdir.'/externallib.php'); + require_once($CFG->libdir.'/moodlelib.php'); + + // Ensure the user exists. + $userid = $DB->get_field('user', 'id', [ 'username' => $username ]); + if (!$userid) { + throw new DriverException("User '$username' not found"); + } + + // Get or create the user token. + $service = $DB->get_record('external_services', ['shortname' => 'moodle_mobile_app']); + + $token_params = [ + 'userid' => $userid, + 'externalserviceid' => $service->id, + ]; + $usertoken = $DB->get_record('external_tokens', $token_params); + if (!$usertoken) { + $context = context_system::instance(); + $token = external_generate_token(EXTERNAL_TOKEN_PERMANENT, $service, $userid, $context); + $token_params['token'] = $token; + $privatetoken = $DB->get_field('external_tokens', 'privatetoken', $token_params); + } else { + $token = $usertoken->token; + $privatetoken = $usertoken->privatetoken; + } + + // Generate custom URL. + $parsed_url = parse_url($CFG->behat_wwwroot); + $domain = $parsed_url['host']; + $url = $this->get_mobile_url_scheme() . "://$username@$domain?token=$token&privatetoken=$privatetoken"; + + if (!empty($path)) { + $url .= '&redirect='.urlencode($CFG->behat_wwwroot.$path); + } else { + $successXPath = '//page-core-mainmenu'; + } + + $this->handle_url_and_wait_page_to_load($url, $successXPath); + } + + /** + * Opens a custom URL on the Moodle App (and waits to finish.) + * + * @param string $path To navigate. + * @param string $successXPath The XPath of the element to lookat after navigation. + */ + protected function open_moodleapp_custom_url(string $path, string $successXPath = '') { + global $CFG; + + $urlscheme = $this->get_mobile_url_scheme(); + $url = "$urlscheme://link=" . urlencode($CFG->behat_wwwroot.$path); + + $this->handle_url_and_wait_page_to_load($url); + } + + /** + * Handles the custom URL on the Moodle App (and waits to finish.) + * + * @param string $customurl To navigate. + * @param string $successXPath The XPath of the element to lookat after navigation. + */ + protected function handle_url_and_wait_page_to_load(string $customurl, string $successXPath = '') { + // Instead of using evaluate_async_script, we wait for the path to load. + $this->evaluate_script("return window.behat.handleCustomURL('$customurl')"); + + $this->wait_for_pending_js(); + + if (!empty($successXPath)) { + // Wait until the page appears. + $this->spin( + function($context, $args) use ($successXPath) { + $found = $context->getSession()->getPage()->find('xpath', $successXPath); + if ($found) { + return true; + } + throw new DriverException('Moodle App custom URL page not loaded'); + }, false, 30); + + // Wait for JS to finish as well. + $this->wait_for_pending_js(); + } + } + + /** + * Returns the current mobile url scheme of the site. + */ + protected function get_mobile_url_scheme() { + $mobilesettings = get_config('tool_mobile'); + + return !empty($mobilesettings->forcedurlscheme) ? $mobilesettings->forcedurlscheme : 'moodlemobile'; + } + + /** + * Get a coursemodule from an activity name or idnumber with course. + * + * @param string $activity + * @param string $identifier + * @param string $coursename + * @return cm_info + */ + protected function get_cm_by_activity_name_and_course(string $activity, string $identifier, string $coursename): cm_info { + global $DB; + + $courseid = $this->get_course_id($coursename); + if (!$courseid) { + throw new DriverException("Course '$coursename' not found"); + } + + if ($activity === 'assignment') { + $activity = 'assign'; + } + + $cmtable = new \core\dml\table('course_modules', 'cm', 'cm'); + $cmfrom = $cmtable->get_from_sql(); + + $acttable = new \core\dml\table($activity, 'a', 'a'); + $actselect = $acttable->get_field_select(); + $actfrom = $acttable->get_from_sql(); + + $sql = <<get_record_sql($sql, [ + 'modname' => $activity, + 'idnumber' => $identifier, + 'name' => $identifier, + 'courseid' => $courseid, + ], MUST_EXIST); + + return get_fast_modinfo($courseid)->get_cm($result->cmid); + } +}