Moving e2e testing to Cypress

This commit is contained in:
Matteo Gheza 2020-09-22 23:58:34 +02:00
parent 1ed42892e3
commit 76c7aae5ff
18 changed files with 402 additions and 2600 deletions

3
server/cypress.json Normal file
View File

@ -0,0 +1,3 @@
{
"baseUrl": "http://localhost:8080"
}

View File

@ -0,0 +1,81 @@
[{
"email": "user1@mail.local",
"name": "Kathy Jordan",
"username": "kathy.jordan",
"password": "4jpbly8g6a",
"birthday": "08/08/1995",
"foreman": false,
"driver": false
}, {
"email": "user2@mail.local",
"name": "Natalie Jordan",
"username": "natalie.jordan",
"password": "kf343di74s",
"birthday": "04/05/2011",
"foreman": true,
"driver": false
}, {
"email": "user3@mail.local",
"name": "Keith Li",
"username": "keith.li",
"password": "3ojvgk4fpv",
"birthday": "11/04/2019",
"foreman": true,
"driver": true
}, {
"email": "user4@mail.local",
"name": "Pellegrino Scotto",
"username": "pellegrino.scotto",
"password": "e0ou92taw3",
"birthday": "20/10/1983",
"foreman": true,
"driver": false
}, {
"email": "user5@mail.local",
"name": "William Torres",
"username": "william.torres",
"password": "0fso8sxxe0",
"birthday": "16/07/2000",
"foreman": false,
"driver": true
}, {
"email": "user6@mail.local",
"name": "Napoleone Tomasetti",
"username": "napoleone.tomasetti",
"password": "so7ykv8a7g",
"birthday": "27/12/1978",
"foreman": true,
"driver": true
}, {
"email": "user7@mail.local",
"name": "Gelsomina Murray",
"username": "gelsomina.murray",
"password": "x1js0s6zao",
"birthday": "22/10/1994",
"foreman": true,
"driver": true
}, {
"email": "user8@mail.local",
"name": "Letizia Petrucelli",
"username": "letizia.petrucelli",
"password": "k1hsbdt3cv",
"birthday": "24/04/1981",
"foreman": true,
"driver": false
}, {
"email": "user9@mail.local",
"name": "Giampaolo Surian",
"username": "giampaolo.surian",
"password": "et52m65s4g",
"birthday": "10/06/1972",
"foreman": true,
"driver": true
}, {
"email": "user10@mail.local",
"name": "Cassandra Jensen",
"username": "cassandra.jensen",
"password": "9h3fb37ccw",
"birthday": "28/10/1985",
"foreman": true,
"driver": false
}]

View File

@ -0,0 +1,111 @@
describe("Installation", () => {
before(() => {
cy.exec("rm config.old.php", {failOnNonZeroExit: false});
cy.exec("mv config.php config.old.php", {failOnNonZeroExit: false});
cy.exec("touch install/runInstall.php", {failOnNonZeroExit: false});
cy.visit("/");
cy.get(".button").click();
})
it('Write wrong DB pwd and user', function () {
cy.get("input[name='dbname']")
.clear()
.type("allerta_db_"+Date.now())
cy.get("input[name='uname']")
.clear()
.type("root_wrongpwd_"+Date.now())
cy.get("input[name='pwd']")
.clear()
.should('have.value', '')
cy.get(".button").click();
cy.contains("Error establishing a database connection");
cy.visit("/");
cy.get(".button").click();
})
it('Write correct DB pwd and user', function () {
cy.get("input[name='dbname']")
.clear()
.type("allerta_db_"+Date.now())
cy.get("input[name='uname']")
.clear()
.type("root")
.should('have.value', 'root')
cy.get("input[name='pwd']")
.clear()
.should('have.value', '')
cy.get(".button").click();
cy.contains("Great job, man!");
cy.get(".button").click();
})
it('Finish installation', function () {
cy.get("input[name='user_name']")
.clear()
.type("admin")
.should('have.value', 'admin')
cy.get("input[name='admin_password']")
.clear()
.type("password")
.should('have.value', 'password')
cy.get("#pass-strength-result")
.should('have.text', 'Very weak')
.should('have.class', 'short')
cy.get("input[name='admin_password']")
.clear()
.type("passsword")
.should('have.value', 'passsword')
cy.get("#pass-strength-result")
.should('have.text', 'Weak')
.should('have.class', 'bad')
cy.get("input[name='admin_password']")
.clear()
.type("Tr0ub4dour&3")
.should('have.value', 'Tr0ub4dour&3')
cy.get("#pass-strength-result")
.should('have.text', 'Good')
.should('have.class', 'good')
cy.get("input[name='admin_password']")
.clear()
.type("#Tr0ub4dour&3#")
.should('have.value', '#Tr0ub4dour&3#')
cy.get("#pass-strength-result")
.should('have.text', 'Strong')
.should('have.class', 'strong')
cy.get("input[name='admin_password']")
.clear()
.type("correcthorsebatterystaple")
.should('have.value', 'correcthorsebatterystaple')
cy.get("#pass-strength-result")
.should('have.text', 'Very strong')
.should('have.class', 'strong')
cy.get("input[name='admin_visible']").check()
cy.get("input[name='admin_email']")
.clear()
.type("admin_email@mail.local")
.should('have.value', 'admin_email@mail.local')
cy.get("input[name='owner']")
.clear()
.type("owner")
.should('have.value', 'owner')
cy.get(".button").click();
cy.contains("Great job, man!");
cy.get(".login").click();
cy.contains("Login");
cy.get(".acceptcookies").should('be.visible');
})
});

View File

@ -0,0 +1,15 @@
describe("Login and logout", () => {
it('Login', function () {
cy.login()
cy.contains("Logs").click()
cy.get("#list").contains("Login")
cy.visit("/logout.php")
cy.contains("Login")
})
it('Logout', function () {
cy.login()
cy.contains("Logs").click()
cy.get("#list").contains("Logout")
})
});

View File

@ -0,0 +1,26 @@
describe("Availability", () => {
beforeEach(() => {
cy.login()
})
it('Change availability to available', function () {
cy.contains('Active').click()
cy.on('window:alert',(txt)=>{
expect(txt).to.contains('Thanks, admin, you have given your availability in case of alert.');
})
cy.get(".fa-check").should('be.visible')
cy.contains("Logs").click()
cy.contains("Attivazione disponibilita'")
cy.visit("/")
})
it('Change availability to not available', function () {
cy.contains('Not Active').click()
cy.on('window:alert',(txt)=>{
expect(txt).to.contains('Thanks, admin, you have removed your availability in case of alert.');
})
cy.get(".fa-times").should('be.visible')
cy.contains("Logs").click()
cy.contains("Rimozione disponibilita'")
cy.visit("/")
})
});

View File

@ -0,0 +1,48 @@
describe("User management", () => {
before(() => {
cy.login()
cy.fixture('users')
.as('users');
})
it('Create users', () => {
cy.get('@users')
.then((users) => {
users.forEach(user => {
name = user.name
console.log(user)
cy.wait(1000)
cy.contains("Add user").click()
cy.get("input[name='mail']")
.clear()
.type(user.email)
.should('have.value', user.email)
cy.get("input[name='name']")
.clear()
.type(user.name)
.should('have.value', user.name)
cy.get("input[name='username']")
.clear()
.type(user.username)
.should('have.value', user.username)
cy.get("input[name='password']")
.clear()
.type(user.password)
.should('have.value', user.password)
cy.get("input[name='birthday']")
.clear()
.type(user.birthday)
.should('have.value', user.birthday)
if(user.foreman){
cy.get("input[name='capo']")
.check({force: true})
}
if(user.driver){
cy.get("input[name='autista']")
.check({force: true})
}
cy.contains("Submit").click()
cy.contains(user.name)
})
})
});
})

View File

@ -0,0 +1,37 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
on('before:browser:launch', (browser = {}, launchOptions) => {
console.log(launchOptions) // print all current args
if (browser.family === 'chromium' && browser.name !== 'electron') {
launchOptions.preferences.default.intl = { accept_languages: "en" }
}
if (browser.family === 'firefox') {
launchOptions.preferences['intl.accept_languages'] = 'en'
}
if (browser.name === 'electron') {
launchOptions.args.push('--lang=en')
launchOptions.preferences.darkTheme = true
}
return launchOptions
})
}

View File

@ -0,0 +1,42 @@
// ***********************************************
// 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", (username="admin", password="correcthorsebatterystaple") => {
cy.visit("/");
cy.getCookie('acceptCookies')
.then((c) => {
if(c == undefined) cy.get(".acceptcookies").click({force: true})
})
cy.get("input[name='name']")
.clear()
.type(username)
.should('have.value', username)
cy.get("input[name='password']")
.clear()
.type(password)
.should('have.value', password)
cy.get("input[name='login']").click()
})
//
//
// -- 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 will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })

View File

@ -0,0 +1,28 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
/*
cy.server({
onAnyRequest: (route, proxy) => {
proxy.xhr.setRequestHeader('CUSTOM-HEADER', 'Header value')
}
})
*/

View File

@ -161,33 +161,36 @@ if(!is_cli()){
var pwd = document.getElementById("pass1").value;
result = zxcvbn(pwd);
switch(result.score) {
case 1:
case 0:
document.getElementById("pass1").className = "short";
document.getElementById("pass-strength-result").className = "short";
document.getElementById("pass-strength-result").innerHTML = "<?php t("Very weak"); ?>";
break;
case 2:
case 1:
document.getElementById("pass1").className = "bad";
document.getElementById("pass-strength-result").className = "bad";
document.getElementById("pass-strength-result").innerHTML = "<?php t("Weak"); ?>";
break;
case 3:
case 2:
document.getElementById("pass1").className = "good";
document.getElementById("pass-strength-result").className = "good";
document.getElementById("pass-strength-result").innerHTML = "<?php t("Good"); ?>";
break;
case 4:
case 3:
document.getElementById("pass1").className = "strong";
document.getElementById("pass-strength-result").className = "strong";
document.getElementById("pass-strength-result").innerHTML = "<?php t("Strong"); ?>";
break;
case 5:
case 4:
document.getElementById("pass1").className = "strong";
document.getElementById("pass-strength-result").className = "strong";
document.getElementById("pass-strength-result").innerHTML = "<?php t("Very strong"); ?>";
break;
default:
// code block
document.getElementById("pass1").className = "short";
document.getElementById("pass-strength-result").className = "short";
document.getElementById("pass-strength-result").innerHTML = "<?php t("Very weak"); ?>";
break;
}
}
</script>
@ -260,7 +263,7 @@ if(!is_cli()){
<h1 class="screen-reader-text"><?php t("Installation completed successfully"); ?>.</h1>
<p><?php t("Great job, man!"); echo(" "); t("You have completed the installation. Allerta can now function properly"); echo(".<br> "); t("If you are ready, it's time to..."); ?></p>
<p class="step">
<a href="../index.php"><?php t("Login"); ?></a>
<a href="../index.php" class="login"><?php t("Login"); ?></a>
</p>
<?php
unlink("runInstall.php");

View File

@ -23,7 +23,7 @@ return [
"Your" => "Il tuo",
"If %s doesn't work, you can get this information from your hosting provider" => "Se %s non funziona, richiedi queste informazioni al tuo fornitore di hosting",
"Edit this item if you want to perform multiple Alert installations on a single database" => "Modifica questo campo se vuoi installare più volte Allerta sullo stesso database",
"Error establishing a database connection" => "Errore nela connessione con il database",
"Error establishing a database connection" => "Errore nella connessione con il database",
"This could mean that %s and %s in file %s are wrong or that we cannot contact database %s. It could mean that your database is unreachable" => "Questo può significare che %s e %s nel file %s sono sbagliati o che il database %s non funziona. Può significare che il database non funziona",
"Are you sure that %s and %s correct?" => "Sei sicuro che %s e %s siano corretti?",
"Are you sure you have entered the correct hostname?" => "Sei sicuro che l'hostname sia corretto?",

View File

@ -1,26 +0,0 @@
<?php
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method void pause()
*
* @SuppressWarnings(PHPMD)
*/
class AcceptanceTester extends \Codeception\Actor
{
use _generated\AcceptanceTesterActions;
/**
* Define custom actions here
*/
}

View File

@ -1,10 +0,0 @@
<?php
namespace Helper;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
class Acceptance extends \Codeception\Module
{
}

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
# Codeception Test Suite Configuration
#
# Suite for acceptance tests.
# Perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.
actor: AcceptanceTester
extensions:
enabled:
- Codeception\Extension\PhpBuiltinServer
config:
Codeception\Extension\PhpBuiltinServer:
hostname: localhost
port: 8000
autostart: true
documentRoot: ../server/
directoryIndex: index.php
startDelay: 1
modules:
enabled:
- PhpBrowser:
url: http://localhost:8000/
- \Helper\Acceptance
step_decorators: ~

View File

@ -1,97 +0,0 @@
<?php
class FirstCest
{
public function installWorks(AcceptanceTester $I)
{
$I->haveServerParameter('HTTP_ACCEPT_LANGUAGE', 'en-US;q=0.5,en;q=0.3');
$I->amOnPage('/install/install.php');
$I->click('Submit');
$I->seeCurrentURLEquals('/install/install.php');
$I->fillField('dbhost', '127.0.0.1');
$I->fillField('uname', 'root');
$I->fillField('pwd', 'password');
$I->click('Submit');
$I->click('Populate DB');
$I->fillField('user_name', 'admin');
$I->fillField('admin_password', 'password');
$I->checkOption('admin_visible');
$I->fillField('admin_email', 'allerta@example.com');
$I->fillField('owner', 'owner');
$I->click('Install Allerta');
$I->see('Login');
$I->click('Login');
$I->fillField('name', 'admin');
$I->fillField('password', 'password');
$I->click('Login');
$I->seeCurrentURLEquals('/list.php');
$I->see('admin');
}
/**
* @depends installWorks
*/
public function logsWorks(AcceptanceTester $I)
{
$I->amOnPage('/list.php');
$I->click('Active');
$I->click('Log');
$I->seeCurrentURLEquals('/log.php');
$I->see('Attivazione disponibilita\'');
$I->click('Lista Disponibilità');
$I->seeCurrentURLEquals('/list.php');
$I->click('Not Active');
$I->seeCurrentURLEquals('/list.php');
$I->click('Log');
$I->seeCurrentURLEquals('/log.php');
$I->see('Rimozione disponibilita\'');
}
/**
* @depends installWorks
*/
public function addUsersWorks(AcceptanceTester $I)
{
$I->amOnPage('/list.php');
$I->click('Add user');
$I->seeCurrentURLEquals('/edit_user.php?add');
/* TODO
$I->click('Lista Disponibilità');
$I->seeCurrentURLEquals('/list.php');
$I->click('Not Active');
$I->seeCurrentURLEquals('/list.php');
$I->click('Log');
$I->seeCurrentURLEquals('/log.php');
$I->see('Rimozione disponibilita\'');
*/
}
//public function servicesWorks(AcceptanceTester $I)
//{
/**
* @var FakerGenerator
*/
/* TODO: Add more users
$faker = \Faker\Factory::create();
$I->amOnPage('/list.php');
$I->click('Services');
$I->seeCurrentURLEquals('/services.php');
$I->click('add service');
$I->seeCurrentURLEquals('/edit_service.php');
$I->fillField('data', '2020-01-01');
$I->fillField('uscita', '12:12');
$I->fillField('rientro', '14:14');
//TODO: check options
$I->type('luogo', $faker->word);
$I->type('note', $faker->word);
$I->click('invia');
$I->seeCurrentURLEquals('/services.php');
$I->see('type2');
*/
//}
}