tao-test/app/tao/views/js/e2e/resourceSelector/resourceTree.js

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