MOBILE-3810 behat: Remove legacy code
parent
0b774fc53c
commit
fc96a23e8a
|
@ -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__) {
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
Loading…
Reference in New Issue