267 lines
8.7 KiB
JavaScript
267 lines
8.7 KiB
JavaScript
/**
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; under version 2
|
|
* of the License (non-upgradable).
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Copyright (c) 2019 (original work) Open Assessment Technologies SA ;
|
|
*/
|
|
|
|
import backOfficeUrls from '../urls/backOfficeUrls';
|
|
import setupSelectors from '../selectors/setupSelectors';
|
|
import runnerSelectors from '../selectors/runnerSelectors';
|
|
|
|
|
|
/**
|
|
* Listen to TaskQueue polling until a response matches
|
|
* @example
|
|
* pollTaskQueue({ category: 'import', status: 'completed' }, 3);
|
|
*
|
|
* @param {Object} criteria - response data parameters we are waiting for
|
|
* @param {String} [criteria.category] - category value we are waiting for
|
|
* @param {String} [criteria.status] - status value we are waiting for
|
|
* @param {Integer} [retries=5] - max number of `getAll` requests to look at before timing out
|
|
*/
|
|
const pollTaskQueue = (criteria, retries = 5) => {
|
|
// Recursive fn with a limit on depth
|
|
const awaitTaskQueue = (retries) => {
|
|
cy.wait('@taskQueueWebApiGetAll', { timeout: 20000 }).then((xhr) => {
|
|
if (xhr.response.body && xhr.response.body.data && xhr.response.body.data.length) {
|
|
cy.log(JSON.stringify(xhr.response.body.data[0])); //
|
|
if (Object.keys(criteria).every((key) => {
|
|
return criteria[key] === xhr.response.body.data[0][key];
|
|
})) {
|
|
// Task Queue entry contains what we're looking for, woohoo
|
|
cy.log(`${JSON.stringify(criteria)} : OK`);
|
|
}
|
|
else if (retries > 0) {
|
|
awaitTaskQueue(retries - 1);
|
|
}
|
|
}
|
|
else if (retries > 0) {
|
|
awaitTaskQueue(retries - 1);
|
|
}
|
|
});
|
|
}
|
|
// begin:
|
|
awaitTaskQueue(retries);
|
|
};
|
|
|
|
/**
|
|
* Archive taoTaskQueue tasks
|
|
* @returns {Promise}
|
|
*/
|
|
const archiveTasks = () => {
|
|
return cy.request({
|
|
url: backOfficeUrls.taskQueueArchiveUrl,
|
|
headers: {
|
|
'X-Requested-With': 'XmlHttpRequest'
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Ping taoTaskQueue via XHR
|
|
* Alias the result so it is available on this.
|
|
* @exposes {Cypress alias<Boolean>} isTaskQueueWorking
|
|
*/
|
|
Cypress.Commands.add('queryTaskQueue', () => {
|
|
cy.log('COMMAND: queryTaskQueue');
|
|
|
|
cy.request({
|
|
url: backOfficeUrls.taskQueueGetUrl,
|
|
headers: {
|
|
'X-Requested-With': 'XmlHttpRequest'
|
|
},
|
|
failOnStatusCode: false // we want to process 4xx and 5xx responses too
|
|
})
|
|
.then(xhr => {
|
|
// Set status on Cypress context
|
|
cy.wrap(xhr.status === 200).as('isTaskQueueWorking');
|
|
});
|
|
});
|
|
|
|
|
|
/**
|
|
* Setup Commands
|
|
*/
|
|
Cypress.Commands.add('importTestPackage', function(fileContent, fileName) {
|
|
cy.log('COMMAND: importTestPackage', fileName);
|
|
|
|
// Check if Task Queue worker is alive (stores isTaskQueueWorking property on context)
|
|
cy.queryTaskQueue();
|
|
|
|
// Visit Tests page
|
|
cy.visit(backOfficeUrls.testsPageUrl);
|
|
|
|
// Wait until page gets loaded and root class gets selected
|
|
cy.wait('@editClassLabel');
|
|
|
|
// Select test import
|
|
cy.get(setupSelectors.testsPage.testImportButton).click();
|
|
|
|
// Wait until test import form is loaded
|
|
cy.get('@isTaskQueueWorking').then(working => {
|
|
if (working) {
|
|
archiveTasks();
|
|
cy.wait('@taskQueueWebApiGetAll');
|
|
}
|
|
});
|
|
// If Task Queue is turned off, or is on but isn't working, we fall back to the synchronous import request:
|
|
cy.wait('@testImportIndex');
|
|
|
|
// Upload example qti test file to file input
|
|
// force:true needed because of a known issue (https://github.com/abramenal/cypress-file-upload/issues/34)
|
|
cy.get(setupSelectors.testsPage.fileInput).upload(
|
|
{
|
|
fileContent,
|
|
fileName: `${fileName}.zip`,
|
|
mimeType: 'application/zip',
|
|
encoding: 'base64'
|
|
},
|
|
{
|
|
subjectType: 'input',
|
|
force: true
|
|
}
|
|
);
|
|
cy.wait('@fileUpload');
|
|
|
|
// Import selected test file
|
|
cy.get(setupSelectors.testsPage.fileImportButton).click();
|
|
|
|
/*
|
|
* Two different processes to handle different UX
|
|
* for taoTaskQueue enabled or disabled
|
|
*/
|
|
cy.get('@isTaskQueueWorking').then(working => {
|
|
if (working) {
|
|
cy.wait(Array(4).fill('@taskQueueWebApi'), { timeout: 20000 });
|
|
|
|
pollTaskQueue({ category: 'import', status: 'completed' });
|
|
|
|
archiveTasks();
|
|
}
|
|
else {
|
|
// Wait until test import request finishes
|
|
cy.wait(['@testImportIndex', '@taskQueueWebApi', '@taskQueueWebApi'], { timeout: 20000 });
|
|
|
|
// Continue
|
|
cy.get(setupSelectors.testsPage.feedbackContinueButton).click();
|
|
|
|
// Wait until publish button appears again
|
|
cy.wait('@editTest');
|
|
}
|
|
})
|
|
});
|
|
|
|
Cypress.Commands.add('publishTest', function(testName, deliveryType = 'local') {
|
|
cy.log('COMMAND: publishTest', testName, deliveryType);
|
|
|
|
// Check if Task Queue worker is alive (stores isTaskQueueWorking property on context)
|
|
cy.queryTaskQueue();
|
|
|
|
// Visit Tests page
|
|
cy.visit(backOfficeUrls.testsPageUrl);
|
|
|
|
// Wait until page gets loaded and root class gets selected
|
|
cy.wait('@editClassLabel');
|
|
|
|
// Select tree node
|
|
cy.get(setupSelectors.testsPage.rootTestClass).within(() => {
|
|
// using 'force: true' because the list item can be off screen
|
|
cy.contains(testName).click({ force: true });
|
|
});
|
|
|
|
cy.wait('@editTest');
|
|
|
|
// Publish selected test
|
|
cy.get(setupSelectors.testsPage.testPublishButton).click();
|
|
|
|
const tenantLabel = Cypress.env('deliverTenantLabel');
|
|
|
|
if (deliveryType === 'remote' && tenantLabel && tenantLabel.length) {
|
|
// Select TAO Remote tab
|
|
cy.get(setupSelectors.testsPage.deliveryTypeTabs).contains('TAO Remote').click();
|
|
// Select suitable tenant
|
|
cy.get('.deliver-tenant-list').select(tenantLabel);
|
|
}
|
|
|
|
// Select Assembled Delivery as root class for publishing
|
|
cy.get(setupSelectors.testsPage.destinationSelector).contains('Assembled Delivery').click();
|
|
|
|
// Clicking on publish
|
|
cy.get(setupSelectors.testsPage.destinationSelectorActions).contains('Publish').click();
|
|
|
|
// Wait until test is published
|
|
if (deliveryType === 'remote') {
|
|
cy.wait('@publishDeliverConnect');
|
|
}
|
|
else {
|
|
cy.wait('@publishDeliveryRdf');
|
|
}
|
|
/*
|
|
* Two different processes to handle different UX
|
|
* for taoTaskQueue enabled or disabled
|
|
*/
|
|
cy.get('@isTaskQueueWorking').then(working => {
|
|
if (working) {
|
|
cy.wait('@taskQueueWebApi', { timeout: 20000 }); // can be 1-4 of them :(
|
|
|
|
if (deliveryType === 'remote') {
|
|
pollTaskQueue({ taskLabel: 'Remote Publication Lookup', status: 'completed' });
|
|
}
|
|
archiveTasks();
|
|
}
|
|
else {
|
|
cy.wait('@editTest');
|
|
}
|
|
});
|
|
});
|
|
|
|
Cypress.Commands.add('setDeliveryForGuests', (testName) => {
|
|
cy.log('COMMAND: setDeliveryForGuests', testName);
|
|
|
|
// Go to Deliveries page
|
|
cy.visit(backOfficeUrls.deliveriesPageUrl);
|
|
|
|
// Wait until page gets loaded and root class gets selected
|
|
cy.wait('@editClassLabel');
|
|
|
|
// Select example delivery
|
|
cy.get(setupSelectors.deliveriesPage.rootDeliveryClass).contains(testName).click();
|
|
|
|
// Set guest access on the delivery (if not yet enabled)
|
|
cy.get(setupSelectors.deliveriesPage.guestAccessCheckbox).check();
|
|
|
|
// Save delivery
|
|
cy.get(setupSelectors.deliveriesPage.formContainer).contains('Save').click();
|
|
|
|
// Wait until save happened properly
|
|
// Not ideal but these requests have to be waited in this order upon delivery save
|
|
cy.wait(['@editDelivery', '@getData','@editDelivery', '@getData', '@editDelivery' ]);
|
|
});
|
|
|
|
Cypress.Commands.add('startTest', (testName) => {
|
|
cy.log('COMMAND: startTest', testName);
|
|
|
|
// Wait for attachment of event listeners to links
|
|
cy.wait(2000);
|
|
|
|
cy.get(runnerSelectors.testList)
|
|
.find(runnerSelectors.availableDeliveries)
|
|
.contains(`Delivery of ${testName}`)
|
|
.click();
|
|
|
|
// The test should be launching now, but it can take several seconds
|
|
cy.wait(['@testRunnerInit', '@testRunnerGetItem'], {timeout: 10000});
|
|
});
|