456 lines
12 KiB
JavaScript
456 lines
12 KiB
JavaScript
/*
|
|
* Copyright (C) 2024 Xibo Signage Ltd
|
|
*
|
|
* Xibo - Digital Signage - https://xibosignage.com
|
|
*
|
|
* This file is part of Xibo.
|
|
*
|
|
* Xibo is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* any later version.
|
|
*
|
|
* Xibo 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 Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
// ***********************************************
|
|
// This example commands.js shows you how to
|
|
// create various custom commands and overwrite
|
|
// existing commands.
|
|
//
|
|
// For more comprehensive examples of custom
|
|
// commands please read more here:
|
|
// https://on.cypress.io/custom-commands
|
|
// ***********************************************
|
|
//
|
|
//
|
|
// -- This is a parent command --
|
|
// Cypress.Commands.add("login", (email, password) => { ... })
|
|
//
|
|
//
|
|
// -- This is a child command --
|
|
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
|
//
|
|
//
|
|
// -- This is a dual command --
|
|
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
|
//
|
|
//
|
|
// -- This is will overwrite an existing command --
|
|
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
|
/* eslint-disable max-len */
|
|
Cypress.Commands.add('login', function(callbackRoute = '/login') {
|
|
cy.session('saveSession', () => {
|
|
cy.visit(callbackRoute);
|
|
cy.request({
|
|
method: 'POST',
|
|
url: '/login',
|
|
form: true,
|
|
body: {
|
|
username: 'xibo_admin',
|
|
password: 'password',
|
|
},
|
|
}).then((res) => {
|
|
// Get access token and save it as a environment variable
|
|
cy.getAccessToken().then(function() {
|
|
cy.getCookie('PHPSESSID').should('exist');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
Cypress.Commands.add('getAccessToken', function() {
|
|
cy.request({
|
|
method: 'POST',
|
|
url: '/api/authorize/access_token',
|
|
form: true,
|
|
body: {
|
|
client_id: Cypress.env('client_id'),
|
|
client_secret: Cypress.env('client_secret'),
|
|
grant_type: 'client_credentials',
|
|
},
|
|
}).then((res) => {
|
|
Cypress.env('accessToken', res.body.access_token);
|
|
});
|
|
});
|
|
|
|
Cypress.Commands.add('tutorialClose', function() {
|
|
const csrf_token = Cypress.$('meta[name="token"]').attr('content');
|
|
|
|
// Make the ajax request to hide the user welcome tutorial
|
|
Cypress.$.ajax({
|
|
url: '/user/welcome',
|
|
type: 'PUT',
|
|
headers: {
|
|
'X-XSRF-TOKEN': csrf_token,
|
|
},
|
|
});
|
|
});
|
|
|
|
Cypress.Commands.add('formRequest', (method, url, formData) => {
|
|
return new Promise(function(resolve, reject) {
|
|
const xhr = new XMLHttpRequest();
|
|
|
|
xhr.open(method, url);
|
|
xhr.setRequestHeader('Authorization', 'Bearer ' + Cypress.env('accessToken'));
|
|
|
|
xhr.onload = function() {
|
|
if (this.status >= 200 && this.status < 300) {
|
|
resolve(xhr.response);
|
|
} else {
|
|
reject({
|
|
status: this.status,
|
|
statusText: xhr.statusText,
|
|
});
|
|
}
|
|
};
|
|
xhr.onerror = function() {
|
|
reject({
|
|
status: this.status,
|
|
statusText: xhr.statusText,
|
|
});
|
|
};
|
|
|
|
xhr.send(formData);
|
|
});
|
|
});
|
|
|
|
Cypress.Commands.add('addMediaToLibrary', (fileName) => {
|
|
// Declarations
|
|
const method = 'POST';
|
|
const url = '/api/library';
|
|
const fileType = '*/*';
|
|
|
|
// Get file from fixtures as binary
|
|
return cy.fixture(fileName, 'binary').then((zipBin) => {
|
|
// File in binary format gets converted to blob so it can be sent as Form data
|
|
const fileBlob = Cypress.Blob.binaryStringToBlob(zipBin, fileType);
|
|
|
|
// Build up the form
|
|
const formData = new FormData();
|
|
|
|
formData.set('files[]', fileBlob, fileName); // adding a file to the form
|
|
|
|
// Perform the request
|
|
return cy.formRequest(method, url, formData).then((response) => {
|
|
const { files } = JSON.parse(response);
|
|
|
|
// Return id
|
|
return files[0].name;
|
|
});
|
|
});
|
|
});
|
|
|
|
// Campaign
|
|
Cypress.Commands.add('createCampaign', function(name) {
|
|
cy.request({
|
|
method: 'POST',
|
|
url: '/api/campaign',
|
|
form: true,
|
|
headers: {
|
|
Authorization: 'Bearer ' + Cypress.env('accessToken'),
|
|
},
|
|
body: {
|
|
name: name,
|
|
},
|
|
}).then((res) => {
|
|
return res.body.campaignId;
|
|
});
|
|
});
|
|
|
|
// Dataset
|
|
Cypress.Commands.add('createDataset', function(name) {
|
|
cy.request({
|
|
method: 'POST',
|
|
url: '/api/dataset',
|
|
form: true,
|
|
headers: {
|
|
Authorization: 'Bearer ' + Cypress.env('accessToken'),
|
|
},
|
|
body: {
|
|
dataSet: name,
|
|
},
|
|
}).then((res) => {
|
|
return res.body.dataSetId;
|
|
});
|
|
});
|
|
|
|
// Delete Dataset
|
|
Cypress.Commands.add('deleteDataset', function(id) {
|
|
cy.request({
|
|
method: 'DELETE',
|
|
url: '/api/dataset/' + id,
|
|
form: true,
|
|
headers: {
|
|
Authorization: 'Bearer ' + Cypress.env('accessToken'),
|
|
},
|
|
body: {},
|
|
}).then((res) => {
|
|
return res;
|
|
});
|
|
});
|
|
|
|
// Sync Group
|
|
Cypress.Commands.add('createSyncGroup', function(name) {
|
|
cy.request({
|
|
method: 'POST',
|
|
url: '/api/syncgroup/add',
|
|
form: true,
|
|
headers: {
|
|
Authorization: 'Bearer ' + Cypress.env('accessToken'),
|
|
},
|
|
body: {
|
|
name: name,
|
|
syncPublisherPort: 9590,
|
|
},
|
|
}).then((res) => {
|
|
return res.body.datasetId;
|
|
});
|
|
});
|
|
|
|
// DayPart
|
|
Cypress.Commands.add('createDayPart', function(name) {
|
|
cy.request({
|
|
method: 'POST',
|
|
url: '/api/daypart',
|
|
form: true,
|
|
headers: {
|
|
Authorization: 'Bearer ' + Cypress.env('accessToken'),
|
|
},
|
|
body: {
|
|
name: name,
|
|
startTime: '01:00:00',
|
|
endTime: '02:00:00',
|
|
},
|
|
}).then((res) => {
|
|
return res.body.dayPartId;
|
|
});
|
|
});
|
|
|
|
// Delete DayPart
|
|
Cypress.Commands.add('deleteDayPart', function(id) {
|
|
cy.request({
|
|
method: 'DELETE',
|
|
url: '/api/daypart/' + id,
|
|
form: true,
|
|
headers: {
|
|
Authorization: 'Bearer ' + Cypress.env('accessToken'),
|
|
},
|
|
body: {},
|
|
}).then((res) => {
|
|
return res;
|
|
});
|
|
});
|
|
|
|
// Tag
|
|
Cypress.Commands.add('createTag', function(name) {
|
|
cy.request({
|
|
method: 'POST',
|
|
url: '/api/tag',
|
|
form: true,
|
|
headers: {
|
|
Authorization: 'Bearer ' + Cypress.env('accessToken'),
|
|
},
|
|
body: {
|
|
name: name,
|
|
},
|
|
}).then((res) => {
|
|
return res.body.id;
|
|
});
|
|
});
|
|
|
|
// Application
|
|
Cypress.Commands.add('createApplication', function(name) {
|
|
cy.request({
|
|
method: 'POST',
|
|
url: '/api/application',
|
|
form: true,
|
|
headers: {
|
|
Authorization: 'Bearer ' + Cypress.env('accessToken'),
|
|
},
|
|
body: {
|
|
name: name,
|
|
},
|
|
}).then((res) => {
|
|
return res.body.key;
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Open playlist editor modal and wait for toolbar user prefs to load
|
|
* @param {String} playlistName
|
|
*/
|
|
Cypress.Commands.add('openPlaylistEditorAndLoadPrefs', function(playlistId) {
|
|
cy.intercept('GET', '/user/pref?preference=toolbar').as('userPrefsLoad');
|
|
|
|
// Reload playlist table page
|
|
cy.visit('/playlist/view');
|
|
|
|
// Clear toolbar preferences
|
|
cy.clearToolbarPrefs();
|
|
|
|
cy.window().then((win) => {
|
|
win.XiboCustomFormRender(win.$('<li class="XiboCustomFormButton playlist_timeline_button_edit" href="/playlist/form/timeline/' + playlistId + '"></li>'));
|
|
|
|
// Wait for user prefs to load
|
|
cy.wait('@userPrefsLoad');
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Add media items to library
|
|
*/
|
|
Cypress.Commands.add('populateLibraryWithMedia', function() {
|
|
// Add audio media to library
|
|
cy.addMediaToLibrary('../assets/audioSample.mp3');
|
|
|
|
// Add image media to library
|
|
cy.addMediaToLibrary('../assets/imageSample.png');
|
|
});
|
|
|
|
/**
|
|
* Drag one element to another one
|
|
* @param {string} draggableSelector
|
|
* @param {string} dropableSelector
|
|
*/
|
|
Cypress.Commands.add('dragToElement', function(draggableSelector, dropableSelector) {
|
|
return cy.get(dropableSelector).then(($el) => {
|
|
const position = {
|
|
x: $el.offset().left + $el.width() / 2 + window.scrollX,
|
|
y: $el.offset().top + $el.height() / 2 + window.scrollY,
|
|
};
|
|
|
|
cy.get(draggableSelector).invoke('show');
|
|
|
|
cy.get(draggableSelector)
|
|
.trigger('mousedown', {
|
|
which: 1,
|
|
})
|
|
.trigger('mousemove', {
|
|
which: 1,
|
|
pageX: position.x,
|
|
pageY: position.y,
|
|
})
|
|
.trigger('mouseup');
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Go to layout editor page and wait for toolbar user prefs to load
|
|
* @param {number} layoutId
|
|
*/
|
|
Cypress.Commands.add('goToLayoutAndLoadPrefs', function(layoutId) {
|
|
cy.intercept('GET', '/user/pref?preference=toolbar').as('userPrefsLoad');
|
|
|
|
cy.clearToolbarPrefs();
|
|
|
|
cy.visit('/layout/designer/' + layoutId);
|
|
|
|
// Wait for user prefs to load
|
|
cy.wait('@userPrefsLoad');
|
|
});
|
|
|
|
Cypress.Commands.add('removeAllSelectedOptions', (select2) => {
|
|
cy.get(select2)
|
|
.as('select2Container');
|
|
|
|
cy.get('@select2Container')
|
|
.then(($select2Container) => {
|
|
if ($select2Container.find('.select2-selection__choice').length > 0) {
|
|
cy.wrap($select2Container)
|
|
.find('.select2-selection__choice')
|
|
.each(($selectedOption) => {
|
|
cy.wrap($selectedOption)
|
|
.find('.select2-selection__choice__remove')
|
|
.click(); // Click on the remove button for each selected option
|
|
});
|
|
} else {
|
|
// No options are selected
|
|
cy.log('No options are selected');
|
|
}
|
|
});
|
|
});
|
|
|
|
// Select an item from the select2 dropdown
|
|
Cypress.Commands.add('selectFromDropdown', (selector, searchText, expected, alias, index = 0) => {
|
|
cy.get(selector).type(searchText);
|
|
|
|
if (alias) {
|
|
cy.wait(alias).its('response.statusCode').should('eq', 200);
|
|
}
|
|
|
|
cy.get('.select2-container--open .select2-dropdown .select2-results > ul')
|
|
.should('contain', expected);
|
|
cy.get('.select2-container--open .select2-dropdown .select2-results > ul > li')
|
|
.eq(index)
|
|
.click();
|
|
});
|
|
|
|
// Select an option from the select2
|
|
Cypress.Commands.add('selectOption', (content) => {
|
|
cy.get('.select2-container--open').contains(content);
|
|
cy.get('.select2-container--open .select2-results > ul > li').should('have.length', 1);
|
|
cy.get('.select2-container--open .select2-results > ul > li:first').contains(content).click();
|
|
});
|
|
|
|
// Schedule a layout
|
|
Cypress.Commands.add('scheduleCampaign', function(campaignId, displayName) {
|
|
cy.request({
|
|
method: 'POST',
|
|
url: '/api/scheduleCampaign',
|
|
form: true,
|
|
headers: {
|
|
Authorization: 'Bearer ' + Cypress.env('accessToken'),
|
|
},
|
|
body: {
|
|
campaignId: campaignId,
|
|
displayName: displayName,
|
|
},
|
|
}).then((res) => {
|
|
return res.body.eventId;
|
|
});
|
|
});
|
|
|
|
// Open Options Menu within the Layout Editor
|
|
Cypress.Commands.add('openOptionsMenu', () => {
|
|
cy.get('.navbar-submenu')
|
|
.should('be.visible')
|
|
.within(() => {
|
|
cy.get('#optionsContainerTop')
|
|
.should('be.visible')
|
|
.and('not.be.disabled')
|
|
.click({force: true})
|
|
.should('have.attr', 'aria-expanded', 'true');
|
|
});
|
|
});
|
|
|
|
// Open Row Menu of the first item on the Layouts page
|
|
Cypress.Commands.add('openRowMenu', () => {
|
|
cy.get('#layouts tbody tr').first().within(() => {
|
|
cy.get('.btn-group .btn.dropdown-toggle')
|
|
.click()
|
|
.should('have.attr', 'aria-expanded', 'true');
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Update data on CKEditor instance
|
|
* @param {string} ckeditorId
|
|
* @param {string} value
|
|
*/
|
|
Cypress.Commands.add('updateCKEditor', function(ckeditorId, value) {
|
|
cy.get('textarea[name="' + ckeditorId + '"]').invoke('prop', 'id').then((id) => {
|
|
cy.window().then((win) => {
|
|
win.formHelpers.getCKEditorInstance(
|
|
id,
|
|
).setData(value);
|
|
});
|
|
});
|
|
});
|