Initial Upload
This commit is contained in:
455
cypress/support/commands.js
Normal file
455
cypress/support/commands.js
Normal file
@@ -0,0 +1,455 @@
|
||||
/*
|
||||
* 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);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user