179 lines
5.9 KiB
JavaScript
179 lines
5.9 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 ;
|
|
*/
|
|
|
|
/**
|
|
* CSS Selectors
|
|
*/
|
|
const selectors = {
|
|
resourceTree: '.resource-tree',
|
|
actionsContainer: '.tree-action-bar',
|
|
contentContainer: '.content-container',
|
|
itemsRootClass: '.class[data-uri="http://www.tao.lu/Ontologies/TAOItem.rdf#Item"]',
|
|
toggler: '.class-toggler',
|
|
treeNode: '.instance, .class',
|
|
labelInput: 'input[name$="label"]',
|
|
saveBtn: '#Save',
|
|
actionBtn: '.action',
|
|
actions: {
|
|
newItem: '.action[data-action="instanciate"]',
|
|
newClass: '.action[data-action="subClass"]',
|
|
deleteItem: '.action[data-action="removeNode"][data-context="instance"]',
|
|
deleteClass: '.action[data-action="removeNode"][data-context="class"]',
|
|
import: '.action[data-action="loadClass"]',
|
|
export: '.action[data-action="load"]',
|
|
moveTo: '.action[data-action="moveTo"]',
|
|
copyTo: '.action[data-action="copyTo"]',
|
|
duplicate: '.action[data-action="duplicateNode"]'
|
|
}
|
|
};
|
|
|
|
export default {
|
|
selectors: selectors
|
|
};
|
|
|
|
/**
|
|
* Commands
|
|
*/
|
|
Cypress.Commands.add('addTreeRoutes', () => {
|
|
cy.route('POST', '**/editItem').as('editItem');
|
|
cy.route('POST', '**/editClassLabel').as('editClass');
|
|
cy.route('POST', '**/deleteItem').as('deleteItem');
|
|
cy.route('POST', '**/deleteClass').as('deleteClass');
|
|
});
|
|
|
|
Cypress.Commands.add('loadItemsPage', () => {
|
|
const fixtures = [];
|
|
|
|
Cypress.Promise.all([
|
|
cy.fixture('urls').then(fx => fixtures.push(fx)),
|
|
cy.fixture('urlParams').then(fx => fixtures.push(fx)),
|
|
])
|
|
.then(() => {
|
|
const [urls, urlParams] = fixtures;
|
|
|
|
// Provide the full URL parameters including 'uri'
|
|
// to guarantee a predictable tree with the 'Item' root class selected
|
|
cy.visit(`${urls.index}?${urlParams.taoItemsRoot}&${urlParams.nosplash}`);
|
|
// Important to register this first response, or it will mess up future "wait"s:
|
|
// Extended timeout because some envs can be slow to load all resources
|
|
cy.wait('@editClass', { timeout: 10000 });
|
|
});
|
|
});
|
|
|
|
Cypress.Commands.add('selectTreeNode', (cssSelector) => {
|
|
cy.log('COMMAND: selectTreeNode', cssSelector);
|
|
|
|
cy.get(selectors.resourceTree).within(() => {
|
|
cy.get(cssSelector)
|
|
.first()
|
|
.then(($el) => {
|
|
const $treeNode = $el.closest(selectors.treeNode);
|
|
|
|
// click the node only if it isn't selected:
|
|
if (!$treeNode.hasClass('selected')) {
|
|
// it can be offscreen due to scrollable panel (so let's force click)
|
|
cy.wrap($treeNode)
|
|
.should('not.have.class', 'selected')
|
|
.click('top', {force: true});
|
|
|
|
// 1 of 2 possible events indicates the clicked node's form loaded:
|
|
if ($treeNode.hasClass('class')) {
|
|
cy.wait('@editClass');
|
|
}
|
|
else {
|
|
cy.wait('@editItem');
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
Cypress.Commands.add('renameSelectedClass', (newName) => {
|
|
cy.log('COMMAND: renameSelectedClass', newName);
|
|
|
|
// assumes that editing form has already been rendered
|
|
cy.get(selectors.contentContainer).within(() => {
|
|
cy.get(selectors.labelInput)
|
|
.clear()
|
|
.type(newName);
|
|
|
|
cy.get(selectors.saveBtn).click();
|
|
});
|
|
// this event needs to fire twice before proceeding
|
|
cy.wait('@editClass').wait('@editClass');
|
|
});
|
|
|
|
Cypress.Commands.add('renameSelectedItem', (newName) => {
|
|
cy.log('COMMAND: renameSelectedItem', newName);
|
|
|
|
// assumes that editing form has already been rendered
|
|
cy.get(selectors.contentContainer).within(() => {
|
|
cy.get(selectors.labelInput)
|
|
.clear()
|
|
.type(newName);
|
|
|
|
cy.get(selectors.saveBtn).click();
|
|
});
|
|
// this event needs to fire twice before proceeding
|
|
cy.wait('@editItem').wait('@editItem');
|
|
});
|
|
|
|
Cypress.Commands.add('addClass', (cssSelector) => {
|
|
cy.log('COMMAND: addClass', cssSelector);
|
|
|
|
cy.selectTreeNode(cssSelector);
|
|
|
|
cy.get(selectors.actions.newClass).click();
|
|
|
|
// this event needs to fire twice before proceeding
|
|
cy.wait('@editClass').wait('@editClass');
|
|
});
|
|
|
|
Cypress.Commands.add('addItem', (cssSelector) => {
|
|
cy.log('COMMAND: addItem', cssSelector);
|
|
|
|
cy.selectTreeNode(cssSelector);
|
|
|
|
cy.get(selectors.actions.newItem).click();
|
|
|
|
// 2 different events must fire before proceeding
|
|
cy.wait('@editClass').wait('@editItem');
|
|
});
|
|
|
|
Cypress.Commands.add('deleteClass', (cssSelector) => {
|
|
cy.log('COMMAND: deleteClass', cssSelector);
|
|
|
|
cy.selectTreeNode(cssSelector);
|
|
|
|
cy.get(selectors.actions.deleteClass).click({force: true});
|
|
cy.get('.modal-body [data-control="ok"]').click();
|
|
|
|
cy.wait('@deleteClass');
|
|
});
|
|
|
|
Cypress.Commands.add('deleteItem', (cssSelector) => {
|
|
cy.log('COMMAND: deleteItem', cssSelector);
|
|
|
|
cy.selectTreeNode(cssSelector);
|
|
|
|
cy.get(selectors.actions.deleteItem).click({force: true});
|
|
cy.get('.modal-body [data-control="ok"]').click();
|
|
|
|
cy.wait('@deleteItem');
|
|
});
|