Skip to content

Commit

Permalink
Cypress Test - Schedule (#1966)
Browse files Browse the repository at this point in the history
  • Loading branch information
ifarzana authored Aug 18, 2023
1 parent 4deb0c1 commit 5941127
Show file tree
Hide file tree
Showing 9 changed files with 398 additions and 10 deletions.
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@ RUN rm /var/www/cms/composer.* && \
rm /var/www/cms/cypress.config.js && \
rm -r /var/www/cms/cypress && \
rm -r /var/www/cms/ui && \
rm /var/www/cms/webpack.config.js
rm /var/www/cms/webpack.config.js && \
rm /var/www/cms/lib/route-cypress.php

# Map a volumes to this folder.
# Our CMS files, library, cache and backups will be in here.
Expand Down
200 changes: 200 additions & 0 deletions cypress/e2e/schedule.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/*
* Copyright (C) 2023 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/>.
*/


/* eslint-disable max-len */
describe('Campaigns', function() {
beforeEach(function() {
cy.login();
});

it('should list all scheduled events', function() {
// Make a GET request to the API endpoint '/schedule/data/events'??
cy.request({
method: 'GET',
url: '/schedule/data/events',
}).then((response) => {
// Assertions on the response
expect(response.status).to.equal(200);
expect(response.body).to.have.property('result');
});
});

it('should schedule an event campaign/layout/command/overlay layout that has no priority, no recurrence', function() {

cy.intercept('/displaygroup?*').as('loadDisplaygroups');
cy.intercept('/campaign?type=list*').as('loadListCampaigns');
cy.intercept('/campaign?isLayoutSpecific=-1*').as('loadLayoutSpecificCampaign');
cy.intercept('/display?start=*').as('loadDisplays');
cy.intercept('/schedule?draw=4&*').as('scheduleGridLoad');
cy.intercept('/layout?*').as('layoutLoad');
cy.intercept('/user/pref').as('userPref');

cy.createCampaign('Campaign for Schedule 1');
cy.createCommand('Set Timezone', 'Set timezone', 'TIMEZONE');

// Intercept the POST request to get the schedule Id
cy.intercept('/schedule').as('postCampaign');

cy.visit('/schedule/view');
cy.contains('Add Event').click();

cy.get('.col-sm-10 > #eventTypeId').select('Campaign', {force: true});
cy.get(':nth-child(3) > .col-sm-10 > .select2 > .selection > .select2-selection > .select2-selection__rendered')
.type('List Campaign Display 1');
// Wait for Display to load
cy.wait('@loadDisplaygroups');
cy.get('.select2-container--open').contains('List Campaign Display 1');
cy.get('.select2-container--open .select2-dropdown .select2-results > ul > li').should('have.length', 2);
cy.get('#select2-displayGroupIds-results > li > ul > li:first').contains('List Campaign Display 1').click();
// cy.get('[name="dayPartId"]').select('Daypart 11-14', {force: true});
cy.get('[name="dayPartId"]').select('Always', {force: true});

// Select Campaign
cy.get('.layout-control > .col-sm-10 > .select2 > .selection > .select2-selection')
.type('Campaign for Schedule 1');
// Wait for Campaign to load
cy.wait('@loadListCampaigns');
cy.get('.select2-container--open').contains('Campaign for Schedule 1');
// cy.get('.select2-container--open .select2-dropdown .select2-results > ul > li').should('have.length', 1);
cy.get('.select2-container--open .select2-results > ul > li').should('have.length', 1);
cy.get('.select2-container--open .select2-results > ul > li:first').contains('Campaign for Schedule 1').click();
cy.get('.modal .modal-footer').contains('Next').click();

// Check toast message
cy.contains('Added Event');
// ---------

// Layout
cy.get('.col-sm-10 > #eventTypeId').select('Layout', {force: true});
// Select Layout
cy.get('.layout-control > .col-sm-10 > .select2 > .selection > .select2-selection')
.type('Layout for Schedule 1');
// Wait for Campaign to load
cy.wait('@loadListCampaigns');
cy.get('.select2-container--open').contains('Layout for Schedule 1');
cy.get('.select2-container--open .select2-dropdown .select2-results > ul > li').should('have.length', 1);
cy.get('.select2-container--open .select2-results > ul > li').should('have.length', 1);
cy.get('.select2-container--open .select2-results > ul > li:first').contains('Layout for Schedule 1').click();
cy.get('.modal .modal-footer').contains('Next').click();

// ---------

// Create Command Schedule
cy.get('.col-sm-10 > #eventTypeId').select('Command', {force: true});

cy.get('.starttime-control > .col-sm-10 > .input-group > .datePickerHelper').click();
cy.get('.open > .flatpickr-innerContainer > .flatpickr-rContainer > .flatpickr-days > .dayContainer > .today').click();
cy.get('.open > .flatpickr-time > :nth-child(3) > .arrowUp').click();
cy.get('[name="commandId"]').select('Set Timezone', {force: true});
cy.get('.modal .modal-footer').contains('Next').click();

// ---------
// Create Overlay Layout Schedule
cy.get('.col-sm-10 > #eventTypeId').select('Overlay Layout', {force: true});
cy.get('[name="dayPartId"]').select('Always', {force: true});

// Select Layout
cy.get('.layout-control > .col-sm-10 > .select2 > .selection > .select2-selection').type('Layout for Schedule 1');
// Wait for Display to load
cy.wait('@loadListCampaigns');
cy.get('.select2-container--open').contains('Layout for Schedule 1');
// cy.get('.select2-container--open .select2-dropdown .select2-results > ul > li').should('have.length', 1);
cy.get('.select2-container--open .select2-results > ul > li').should('have.length', 1);
cy.get('.select2-container--open .select2-results > ul > li:first').contains('Layout for Schedule 1').click();

cy.get(':nth-child(3) > .col-sm-10 > .select2 > .selection > .select2-selection > .select2-selection__rendered')
.type('List Campaign Display 1');
// Wait for Display to load
cy.wait('@loadDisplaygroups');
cy.get('.select2-container--open').contains('List Campaign Display 1');
cy.get('.select2-container--open .select2-dropdown .select2-results > ul > li').should('have.length', 2);
cy.get('#select2-displayGroupIds-results > li > ul > li:first').contains('List Campaign Display 1').click();

cy.get('.modal .modal-footer').contains('Save').click();

// ------
// Check if schedule creation was successful
cy.visit('/schedule/view');

cy.get('#DisplayList + span .select2-selection').click();
cy.wait('@loadDisplays');
// Type the display name
cy.get('.select2-container--open input[type="search"]').type('List Campaign Display 1');

// Wait for Display to load
cy.wait('@loadDisplays');
cy.get('.select2-container--open').contains('List Campaign Display 1');
cy.get('.select2-container--open .select2-results > ul > li').should('have.length', 1);
cy.get('.select2-container--open .select2-results > ul > li:first').contains('List Campaign Display 1').click();

cy.get('#schedule-grid').contains('Campaign for Schedule 1');
cy.get('#schedule-grid').contains('Layout for Schedule 1');
});

it('should edit a scheduled event', function() {
cy.intercept('/user/pref').as('userPref');
cy.intercept('/schedule?draw=*').as('scheduleGridLoad');

cy.intercept('/displaygroup?*').as('loadDisplaygroups');
cy.intercept('/campaign?isLayoutSpecific=-1*').as('loadLayoutSpecificCampaign');

cy.visit('/schedule/view');

// ---------
// Edit a schedule - add another display
cy.get('#campaignIdFilter + span .select2-selection').click();
cy.wait('@loadLayoutSpecificCampaign');
cy.get('.select2-container--open input[type="search"]').type('Layout for Schedule 1'); // Type the layout name
cy.wait('@loadLayoutSpecificCampaign');
cy.get('.select2-container--open').contains('Layout for Schedule 1');
cy.get('.select2-container--open .select2-results > ul > li').should('have.length', 1);
cy.get('.select2-container--open .select2-results > ul > li:first').contains('Layout for Schedule 1').click();

// Should have 1
cy.get('#schedule-grid tbody tr').should('have.length', 2);
cy.get('#schedule-grid tr:first-child .dropdown-toggle').click();
cy.get('#schedule-grid tr:first-child .schedule_button_edit').click();

cy.get(':nth-child(3) > .col-sm-10 > .select2 > .selection > .select2-selection > .select2-selection__rendered')
.type('List Campaign Display 2');
// Wait for Display to load
cy.wait('@loadDisplaygroups');
cy.get('.select2-container--open').contains('List Campaign Display 2');
cy.get('.select2-container--open .select2-dropdown .select2-results > ul > li').should('have.length', 2);
cy.get('#select2-displayGroupIds-results > li > ul > li:first').contains('List Campaign Display 2').click();
cy.get('.modal .modal-footer').contains('Save').click();
cy.get('#schedule-grid tbody').contains('2');

// ---------
// Delete the schedule
// cy.get('#schedule-grid tbody tr').should('have.length', 2);
// cy.wait('@scheduleGridLoad');
// cy.wait('@userPref');
// cy.wait('@scheduleGridLoad');
// cy.get('#schedule-grid tr:first-child .dropdown-toggle').click();
// cy.get('#schedule-grid tr:first-child .schedule_button_delete').click();
// cy.get('.bootbox .save-button').click();
//
// // Validate the schedule no longer exist
// cy.get('#schedule-grid tbody tr').should('have.length', 1);
});
});
36 changes: 36 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,42 @@ Cypress.Commands.add('scheduleCampaign', function(campaignId, displayName) {
});
});

// Create a campaign
Cypress.Commands.add('createCampaign', function(campaignName) {
cy.request({
method: 'POST',
url: '/api/createCampaign',
form: true,
headers: {
Authorization: 'Bearer ' + Cypress.env('accessToken'),
},
body: {
name: campaignName,
},
}).then((res) => {
return res.body.campaignId;
});
});

// Create a command
Cypress.Commands.add('createCommand', function(name, description, code) {
cy.request({
method: 'POST',
url: '/api/createCommand',
form: true,
headers: {
Authorization: 'Bearer ' + Cypress.env('accessToken'),
},
body: {
command: name,
description: description,
code: code,
},
}).then((res) => {
return res.body.commandId;
});
});

// Set Display Status
Cypress.Commands.add('displaySetStatus', function(displayName, statusId) {
cy.request({
Expand Down
103 changes: 102 additions & 1 deletion lib/Controller/CypressTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
use Slim\Http\ServerRequest as Request;
use Xibo\Entity\Display;
use Xibo\Factory\CampaignFactory;
use Xibo\Factory\CommandFactory;
use Xibo\Factory\DayPartFactory;
use Xibo\Factory\DisplayFactory;
use Xibo\Factory\DisplayGroupFactory;
use Xibo\Factory\FolderFactory;
use Xibo\Factory\LayoutFactory;
use Xibo\Factory\ScheduleFactory;
use Xibo\Helper\Session;
Expand Down Expand Up @@ -58,6 +60,13 @@ class CypressTest extends Base
*/
private $scheduleFactory;

/** @var FolderFactory */
private $folderFactory;
/**
* @var CommandFactory
*/
private $commandFactory;

/**
* @var DisplayGroupFactory
*/
Expand Down Expand Up @@ -97,7 +106,9 @@ public function __construct(
$campaignFactory,
$displayFactory,
$layoutFactory,
$dayPartFactory
$dayPartFactory,
$folderFactory,
$commandFactory
) {
$this->store = $store;
$this->session = $session;
Expand All @@ -107,8 +118,12 @@ public function __construct(
$this->displayFactory = $displayFactory;
$this->layoutFactory = $layoutFactory;
$this->dayPartFactory = $dayPartFactory;
$this->folderFactory = $folderFactory;
$this->commandFactory = $commandFactory;
}

// <editor-fold desc="Displays">

/**
* @throws InvalidArgumentException
* @throws ControllerNotImplemented
Expand Down Expand Up @@ -241,4 +256,90 @@ public function displayStatusEquals(Request $request, Response $response): Respo

return $this->render($request, $response);
}

// </editor-fold>

public function createCommand(Request $request, Response $response): Response|ResponseInterface
{
$sanitizedParams = $this->getSanitizer($request->getParams());

$command = $this->commandFactory->create();
$command->command = $sanitizedParams->getString('command');
$command->description = $sanitizedParams->getString('description');
$command->code = $sanitizedParams->getString('code');
$command->userId = $this->getUser()->userId;
$command->commandString = $sanitizedParams->getString('commandString');
$command->validationString = $sanitizedParams->getString('validationString');
$availableOn = $sanitizedParams->getArray('availableOn');
if (empty($availableOn)) {
$command->availableOn = null;
} else {
$command->availableOn = implode(',', $availableOn);
}
$command->save();

// Return
$this->getState()->hydrate([
'httpStatus' => 201,
'message' => sprintf(__('Added %s'), $command->command),
'id' => $command->commandId,
'data' => $command
]);

return $this->render($request, $response);
}

/**
* @throws InvalidArgumentException
* @throws ControllerNotImplemented
* @throws NotFoundException
* @throws GeneralException
*/
public function createCampaign(Request $request, Response $response): Response|ResponseInterface
{
$this->getLog()->debug('Creating campaign');
$sanitizedParams = $this->getSanitizer($request->getParams());

$folder = $this->folderFactory->getById($this->getUser()->homeFolderId, 0);

// Create Campaign
$campaign = $this->campaignFactory->create(
'list',
$sanitizedParams->getString('name'),
$this->getUser()->userId,
$folder->getId()
);

// Cycle based playback
if ($campaign->type === 'list') {
$campaign->cyclePlaybackEnabled = $sanitizedParams->getCheckbox('cyclePlaybackEnabled');
$campaign->playCount = ($campaign->cyclePlaybackEnabled) ? $sanitizedParams->getInt('playCount') : null;

// For compatibility with existing API implementations we set a default here.
$campaign->listPlayOrder = ($campaign->cyclePlaybackEnabled)
? 'block'
: $sanitizedParams->getString('listPlayOrder', ['default' => 'round']);
} else if ($campaign->type === 'ad') {
$campaign->targetType = $sanitizedParams->getString('targetType');
$campaign->target = $sanitizedParams->getInt('target');
$campaign->listPlayOrder = 'round';
}

// All done, save.
$campaign->save();

// Return
$this->getState()->hydrate([
'httpStatus' => 201,
'message' => __('Added campaign'),
'id' => $campaign->campaignId,
'data' => $campaign
]);

return $this->render($request, $response);
}

// <editor-fold desc="Schedule">

// </editor-fold>
}
Loading

0 comments on commit 5941127

Please sign in to comment.