Merge pull request #71 from crazyserver/integration-pau

Integration pau
main
Noel De Martin 2022-02-23 11:31:15 +01:00 committed by GitHub
commit 462e868582
10 changed files with 129 additions and 48 deletions

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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;

View File

@ -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');

View File

@ -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

View File

@ -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