1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-18 23:42:25 +02:00

Initial acceptance tests

This commit is contained in:
Hillel Coren 2015-08-20 18:09:04 +03:00
parent 660d3ba32d
commit 95fd9a4c1c
41 changed files with 5189 additions and 366 deletions

3
.gitignore vendored
View File

@ -28,4 +28,5 @@
/.phpstorm.meta.php
/_ide_helper.php
/.idea
/.project
/.project
tests/_output/

View File

@ -116,18 +116,18 @@ class DashboardController extends BaseController
$data = [
'account' => Auth::user()->account,
'paidToDate' => $paidToDate,
'balances' => $balances,
'averageInvoice' => $averageInvoice,
'invoicesSent' => $metrics ? $metrics->invoices_sent : 0,
'activeClients' => $metrics ? $metrics->active_clients : 0,
'activities' => $activities,
'pastDue' => $pastDue,
'upcoming' => $upcoming,
'payments' => $payments,
'title' => trans('texts.dashboard'),
];
'account' => Auth::user()->account,
'paidToDate' => $paidToDate,
'balances' => $balances,
'averageInvoice' => $averageInvoice,
'invoicesSent' => $metrics ? $metrics->invoices_sent : 0,
'activeClients' => $metrics ? $metrics->active_clients : 0,
'activities' => $activities,
'pastDue' => $pastDue,
'upcoming' => $upcoming,
'payments' => $payments,
'title' => trans('texts.dashboard'),
];
return View::make('dashboard', $data);
}

View File

@ -75,7 +75,7 @@ class StartupCheck
$count = Session::get(SESSION_COUNTER, 0);
Session::put(SESSION_COUNTER, ++$count);
if (!Utils::startsWith($_SERVER['REQUEST_URI'], '/news_feed') && !Session::has('news_feed_id')) {
if (isset($_SERVER['REQUEST_URI']) && !Utils::startsWith($_SERVER['REQUEST_URI'], '/news_feed') && !Session::has('news_feed_id')) {
$data = false;
if (Utils::isNinja()) {
$data = Utils::getNewsFeedResponse();
@ -128,36 +128,38 @@ class StartupCheck
}
// Check if the user is claiming a license (ie, additional invoices, white label, etc.)
$claimingLicense = Utils::startsWith($_SERVER['REQUEST_URI'], '/claim_license');
if (!$claimingLicense && Input::has('license_key') && Input::has('product_id')) {
$licenseKey = Input::get('license_key');
$productId = Input::get('product_id');
if (isset($_SERVER['REQUEST_URI'])) {
$claimingLicense = Utils::startsWith($_SERVER['REQUEST_URI'], '/claim_license');
if (!$claimingLicense && Input::has('license_key') && Input::has('product_id')) {
$licenseKey = Input::get('license_key');
$productId = Input::get('product_id');
$data = trim(file_get_contents((Utils::isNinjaDev() ? SITE_URL : NINJA_APP_URL)."/claim_license?license_key={$licenseKey}&product_id={$productId}"));
if ($productId == PRODUCT_INVOICE_DESIGNS) {
if ($data = json_decode($data)) {
foreach ($data as $item) {
$design = new InvoiceDesign();
$design->id = $item->id;
$design->name = $item->name;
$design->javascript = $item->javascript;
$design->save();
$data = trim(file_get_contents((Utils::isNinjaDev() ? SITE_URL : NINJA_APP_URL)."/claim_license?license_key={$licenseKey}&product_id={$productId}"));
if ($productId == PRODUCT_INVOICE_DESIGNS) {
if ($data = json_decode($data)) {
foreach ($data as $item) {
$design = new InvoiceDesign();
$design->id = $item->id;
$design->name = $item->name;
$design->javascript = $item->javascript;
$design->save();
}
Session::flash('message', trans('texts.bought_designs'));
}
} elseif ($productId == PRODUCT_WHITE_LABEL) {
if ($data == 'valid') {
$account = Auth::user()->account;
$account->pro_plan_paid = NINJA_DATE;
$account->save();
Session::flash('message', trans('texts.bought_designs'));
}
} elseif ($productId == PRODUCT_WHITE_LABEL) {
if ($data == 'valid') {
$account = Auth::user()->account;
$account->pro_plan_paid = NINJA_DATE;
$account->save();
Session::flash('message', trans('texts.bought_white_label'));
Session::flash('message', trans('texts.bought_white_label'));
}
}
}
}
if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(?i)msie [2-8]/', $_SERVER['HTTP_USER_AGENT'])) {
Session::flash('error', trans('texts.old_browser'));
}

View File

@ -1,6 +1,5 @@
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
@ -27,6 +26,13 @@ Route::post('setup', 'AppController@doSetup');
Route::get('install', 'AppController@install');
Route::get('update', 'AppController@update');
/*
// Codeception code coverage
Route::get('/c3.php', function () {
include '../c3.php';
});
*/
// Public pages
Route::get('/', 'HomeController@showIndex');
Route::get('terms', 'HomeController@showTerms');
@ -393,6 +399,9 @@ define('USER_TYPE_SELF_HOST', 'SELF_HOST');
define('USER_TYPE_CLOUD_HOST', 'CLOUD_HOST');
define('NEW_VERSION_AVAILABLE', 'NEW_VERSION_AVAILABLE');
define('TEST_USERNAME', 'user@email.com');
define('TEST_PASSWORD', 'password');
define('TOKEN_BILLING_DISABLED', 1);
define('TOKEN_BILLING_OPT_IN', 2);
define('TOKEN_BILLING_OPT_OUT', 3);
@ -405,14 +414,6 @@ define('PAYMENT_TYPE_DWOLLA', 'PAYMENT_TYPE_DWOLLA');
define('PAYMENT_TYPE_TOKEN', 'PAYMENT_TYPE_TOKEN');
define('PAYMENT_TYPE_ANY', 'PAYMENT_TYPE_ANY');
/*
define('GATEWAY_AMAZON', 30);
define('GATEWAY_BLUEPAY', 31);
define('GATEWAY_BRAINTREE', 32);
define('GATEWAY_GOOGLE', 33);
define('GATEWAY_QUICKBOOKS', 35);
*/
$creditCards = [
1 => ['card' => 'images/credit_cards/Test-Visa-Icon.png', 'text' => 'Visa'],
2 => ['card' => 'images/credit_cards/Test-MasterCard-Icon.png', 'text' => 'Master Card'],
@ -469,7 +470,6 @@ Event::listen('illuminate.query', function($query, $bindings, $time, $name)
});
*/
/*
if (Auth::check() && Auth::user()->id === 1)
{

View File

@ -72,7 +72,7 @@ class AppServiceProvider extends ServiceProvider {
// Get the breadcrumbs by exploding the current path.
$basePath = Utils::basePath();
$parts = explode('?', $_SERVER['REQUEST_URI']);
$parts = explode('?', isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '');
$path = $parts[0];
if ($basePath != '/') {

240
c3.php Executable file
View File

@ -0,0 +1,240 @@
<?php
// @codingStandardsIgnoreFile
// @codeCoverageIgnoreStart
/**
* C3 - Codeception Code Coverage
*
* @author tiger
*/
// $_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_DEBUG'] = 1;
if (isset($_COOKIE['CODECEPTION_CODECOVERAGE'])) {
$cookie = json_decode($_COOKIE['CODECEPTION_CODECOVERAGE'], true);
// fix for improperly encoded JSON in Code Coverage cookie with WebDriver.
// @see https://github.com/Codeception/Codeception/issues/874
if (!is_array($cookie)) {
$cookie = json_decode($cookie, true);
}
if ($cookie) {
foreach ($cookie as $key => $value) {
$_SERVER["HTTP_X_CODECEPTION_".strtoupper($key)] = $value;
}
}
}
if (!array_key_exists('HTTP_X_CODECEPTION_CODECOVERAGE', $_SERVER)) {
return;
}
if (!function_exists('__c3_error')) {
function __c3_error($message)
{
file_put_contents(C3_CODECOVERAGE_MEDIATE_STORAGE . DIRECTORY_SEPARATOR . 'error.txt', $message);
if (!headers_sent()) {
header('X-Codeception-CodeCoverage-Error: ' . str_replace("\n", ' ', $message), true, 500);
}
setcookie('CODECEPTION_CODECOVERAGE_ERROR', $message);
}
}
// Autoload Codeception classes
if (!class_exists('\\Codeception\\Codecept')) {
if (stream_resolve_include_path(__DIR__ . '/vendor/autoload.php')) {
require_once __DIR__ . '/vendor/autoload.php';
} elseif (file_exists(__DIR__ . '/codecept.phar')) {
require_once 'phar://'.__DIR__ . '/codecept.phar/autoload.php';
} elseif (stream_resolve_include_path('Codeception/autoload.php')) {
require_once 'Codeception/autoload.php';
} else {
__c3_error('Codeception is not loaded. Please check that either PHAR or Composer or PEAR package can be used');
}
}
// Load Codeception Config
$config_file = realpath(__DIR__) . DIRECTORY_SEPARATOR . 'codeception.yml';
if (isset($_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_CONFIG'])) {
$config_file = realpath(__DIR__) . DIRECTORY_SEPARATOR . $_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_CONFIG'];
}
if (!file_exists($config_file)) {
__c3_error(sprintf("Codeception config file '%s' not found", $config_file));
}
try {
\Codeception\Configuration::config($config_file);
} catch (\Exception $e) {
__c3_error($e->getMessage());
}
if (!defined('C3_CODECOVERAGE_MEDIATE_STORAGE')) {
// workaround for 'zend_mm_heap corrupted' problem
gc_disable();
if ((integer)ini_get('memory_limit') < 384) {
ini_set('memory_limit', '384M');
}
define('C3_CODECOVERAGE_MEDIATE_STORAGE', Codeception\Configuration::logDir() . 'c3tmp');
define('C3_CODECOVERAGE_PROJECT_ROOT', Codeception\Configuration::projectDir());
define('C3_CODECOVERAGE_TESTNAME', $_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE']);
function __c3_build_html_report(PHP_CodeCoverage $codeCoverage, $path)
{
$writer = new PHP_CodeCoverage_Report_HTML();
$writer->process($codeCoverage, $path . 'html');
if (file_exists($path . '.tar')) {
unlink($path . '.tar');
}
$phar = new PharData($path . '.tar');
$phar->setSignatureAlgorithm(Phar::SHA1);
$files = $phar->buildFromDirectory($path . 'html');
array_map('unlink', $files);
if (in_array('GZ', Phar::getSupportedCompression())) {
if (file_exists($path . '.tar.gz')) {
unlink($path . '.tar.gz');
}
$phar->compress(\Phar::GZ);
// close the file so that we can rename it
unset($phar);
unlink($path . '.tar');
rename($path . '.tar.gz', $path . '.tar');
}
return $path . '.tar';
}
function __c3_build_clover_report(PHP_CodeCoverage $codeCoverage, $path)
{
$writer = new PHP_CodeCoverage_Report_Clover();
$writer->process($codeCoverage, $path . '.clover.xml');
return $path . '.clover.xml';
}
function __c3_send_file($filename)
{
if (!headers_sent()) {
readfile($filename);
}
return __c3_exit();
}
/**
* @param $filename
* @return null|PHP_CodeCoverage
*/
function __c3_factory($filename)
{
$phpCoverage = is_readable($filename)
? unserialize(file_get_contents($filename))
: new PHP_CodeCoverage();
if (isset($_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_SUITE'])) {
$suite = $_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_SUITE'];
try {
$settings = \Codeception\Configuration::suiteSettings($suite, \Codeception\Configuration::config());
} catch (Exception $e) {
__c3_error($e->getMessage());
}
} else {
$settings = \Codeception\Configuration::config();
}
try {
\Codeception\Coverage\Filter::setup($phpCoverage)
->whiteList($settings)
->blackList($settings);
} catch (Exception $e) {
__c3_error($e->getMessage());
}
return $phpCoverage;
}
function __c3_exit()
{
if (!isset($_SERVER['HTTP_X_CODECEPTION_CODECOVERAGE_DEBUG'])) {
exit;
}
return null;
}
function __c3_clear()
{
\Codeception\Util\FileSystem::doEmptyDir(C3_CODECOVERAGE_MEDIATE_STORAGE);
}
}
if (!is_dir(C3_CODECOVERAGE_MEDIATE_STORAGE)) {
if (mkdir(C3_CODECOVERAGE_MEDIATE_STORAGE, 0777, true) === false) {
__c3_error('Failed to create directory "' . C3_CODECOVERAGE_MEDIATE_STORAGE . '"');
}
}
// evaluate base path for c3-related files
$path = realpath(C3_CODECOVERAGE_MEDIATE_STORAGE) . DIRECTORY_SEPARATOR . 'codecoverage';
$requested_c3_report = (strpos($_SERVER['REQUEST_URI'], 'c3/report') !== false);
$complete_report = $current_report = $path . '.serialized';
if ($requested_c3_report) {
set_time_limit(0);
$route = ltrim(strrchr($_SERVER['REQUEST_URI'], '/'), '/');
if ($route == 'clear') {
__c3_clear();
return __c3_exit();
}
$codeCoverage = __c3_factory($complete_report);
switch ($route) {
case 'html':
try {
__c3_send_file(__c3_build_html_report($codeCoverage, $path));
} catch (Exception $e) {
__c3_error($e->getMessage());
}
return __c3_exit();
case 'clover':
try {
__c3_send_file(__c3_build_clover_report($codeCoverage, $path));
} catch (Exception $e) {
__c3_error($e->getMessage());
}
return __c3_exit();
case 'serialized':
try {
__c3_send_file($complete_report);
} catch (Exception $e) {
__c3_error($e->getMessage());
}
return __c3_exit();
}
} else {
$codeCoverage = __c3_factory($current_report);
$codeCoverage->start(C3_CODECOVERAGE_TESTNAME);
if (!array_key_exists('HTTP_X_CODECEPTION_CODECOVERAGE_DEBUG', $_SERVER)) {
register_shutdown_function(
function () use ($codeCoverage, $current_report) {
$codeCoverage->stop();
file_put_contents($current_report, serialize($codeCoverage));
}
);
}
}
// @codeCoverageIgnoreEnd

27
codeception.yml Normal file
View File

@ -0,0 +1,27 @@
actor: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
settings:
bootstrap: _bootstrap.php
colors: true
memory_limit: 1024M
extensions:
enabled:
- Codeception\Extension\RunFailed
- Codeception\Extension\Recorder
config:
Codeception\Extension\Recorder:
delete_successful: false
modules:
config:
Db:
dsn: 'mysql:dbname=ninja;host=localhost;'
user: 'ninja'
password: 'ninja'
dump: tests/_data/dump.sql
populate: true
cleanup: false

View File

@ -37,11 +37,14 @@
"guzzlehttp/guzzle": "~5.0",
"laravelcollective/html": "~5.0",
"wildbit/laravel-postmark-provider": "dev-master",
"Dwolla/omnipay-dwolla": "dev-master"
"Dwolla/omnipay-dwolla": "dev-master"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"phpspec/phpspec": "~2.1"
"phpspec/phpspec": "~2.1",
"codeception/codeception": "~2.0",
"codeception/c3": "~2.0",
"fzaninotto/faker": "^1.5"
},
"autoload": {
"classmap": [

1081
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -13,14 +13,14 @@ class DatabaseSeeder extends Seeder {
Eloquent::unguard();
$this->call('UserTableSeeder');
$this->call('ConstantsSeeder');
$this->command->info('Seeded the constants');
$this->call('CountriesSeeder');
$this->command->info('Seeded the countries!');
$this->command->info('Seeded the countries');
$this->call('PaymentLibrariesSeeder');
$this->command->info('Seeded the Payment Libraries!');
$this->command->info('Seeded the Payment Libraries');
}
}

View File

@ -1,11 +1,29 @@
<?php
use App\Models\User;
use App\Models\Account;
class UserTableSeeder extends Seeder
{
public function run()
{
$this->command->info('Running UserTableSeeder');
Eloquent::unguard();
$account = Account::create([
'name' => 'Test Account',
'account_key' => str_random(16),
'timezone_id' => 1,
]);
User::create([
'email' => TEST_USERNAME,
'username' => TEST_USERNAME,
'account_id' => $account->id,
'password' => Hash::make(TEST_PASSWORD),
]);
}
}

View File

@ -743,17 +743,17 @@
'manage_companies' => 'Manage Companies',
'total_revenue' => 'Total Revenue',
'current_user' => 'Current User',
'new_recurring_invoice' => 'New Recurring Invoice',
'recurring_invoice' => 'Recurring Invoice',
'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice',
'created_by_invoice' => 'Created by :invoice',
'primary_user' => 'Primary User',
'help' => 'Help',
'customize_help' => '<p>We use <a href="http://pdfmake.org/" target="_blank">pdfmake</a> to define the invoice designs declaratively. The pdfmake <a href="http://pdfmake.org/playground.html" target="_blank">playground</a> provide\'s a great way to see the library in action.</p>
<p>You can access any invoice field by adding <code>Value</code> to the end. For example <code>$invoiceNumberValue</code> displays the invoice number.</p>
<p>To access a child property using dot notation. For example to show the client name you could use <code>$client.nameValue</code>.</p>
<p>If you need help figuring something out post a question to our <a href="https://www.invoiceninja.com/forums/forum/support/" target="_blank">support forum</a>.</p>'
'current_user' => 'Nuværende bruger',
'new_recurring_invoice' => 'Ny gentaget fakture',
'recurring_invoice' => 'Gentaget faktura',
'recurring_too_soon' => 'Det er for tidligt at generere den næste faktura',
'created_by_invoice' => 'Oprettet fra :invoice',
'primary_user' => 'Primær bruger',
'help' => 'Hlp',
'customize_help' => '<p>Vi bruger <a href="http://pdfmake.org/" target="_blank">pdfmake</a> til at definere faktura design felter. pdfmake <a href="http://pdfmake.org/playground.html" target="_blank">legeplads</a> giver en god mulighed for at se biblioteket i aktion.</p>
<p>Du kan tilgå alle faktura felter ved at tilføje <code>Value</code> til slutningen. For eksempel viser <code>$invoiceNumberValue</code> fakturanummeret.</p>
<p>For at tilgå under indstillingerne ved hjælp af dot notation. For eksempel kan man for at vise klient navnet bruge <code>$client.nameValue</code>.</p>
<p>Hvis du mangler svar nogen spørgsmål post et spørgsmål i vores <a href="https://www.invoiceninja.com/forums/forum/support/" target="_blank">support forum</a>.</p>',
);

View File

@ -46,7 +46,7 @@ return array(
'line_total' => 'Summe',
'subtotal' => 'Zwischensumme',
'paid_to_date' => 'Bereits gezahlt',
'balance_due' => 'Rechnungsbetrag',
'balance_due' => 'Geschuldeter Betrag',
'invoice_design_id' => 'Design',
'terms' => 'Bedingungen',
'your_invoice' => 'Ihre Rechnung',

View File

@ -574,6 +574,7 @@ return array(
'forgot_password' => 'Forgot your password?',
'email_address' => 'Email address',
'lets_go' => 'Let\'s go',
//'lets_go' => 'Login',
'password_recovery' => 'Password Recovery',
'send_email' => 'Send email',
'set_password' => 'Set Password',

View File

@ -100,7 +100,7 @@
<div class="pull-right" style="padding-top: 6px">
{!! trans('texts.created_by_invoice', ['invoice' => link_to('/invoices/'.$invoice->recurring_invoice->public_id, trans('texts.recurring_invoice'))]) !!}
</div>
@elseif ($invoice && $invoice->last_sent_date)
@elseif ($invoice && $invoice->last_sent_date && $invoice->recurring_invoices->last())
<div class="pull-right" style="padding-top: 6px">
{!! trans('texts.last_invoice_sent', [
'date' => link_to('/invoices/'.$invoice->recurring_invoices->last()->public_id, Utils::dateToString($invoice->last_sent_date))
@ -336,7 +336,7 @@
@if (!$invoice || (!$invoice->trashed() && !$invoice->client->trashed()))
{!! Button::success(trans("texts.save_{$entityType}"))->withAttributes(array('id' => 'saveButton', 'onclick' => 'onSaveClick()'))->appendIcon(Icon::create('floppy-disk')) !!}
{!! Button::info(trans("texts.email_{$entityType}"))->withAttributes(array('id' => 'email_button', 'onclick' => 'onEmailClick()'))->appendIcon(Icon::create('send')) !!}
{!! Button::info(trans("texts.email_{$entityType}"))->withAttributes(array('id' => 'emailButton', 'onclick' => 'onEmailClick()'))->appendIcon(Icon::create('send')) !!}
@if ($invoice && $invoice->id)
{!! DropdownButton::normal(trans('texts.more_actions'))
@ -1777,10 +1777,10 @@
function onRecurringEnabled()
{
if ($('#recurring').prop('checked')) {
$('#email_button').attr('disabled', true);
$('#emailButton').attr('disabled', true);
model.invoice().partial('');
} else {
$('#email_button').removeAttr('disabled');
$('#emailButton').removeAttr('disabled');
}
}

6
tests/_bootstrap.php Normal file
View File

@ -0,0 +1,6 @@
<?php
// This is global bootstrap for autoloading
use Codeception\Util\Fixtures;
Fixtures::add('username', 'user@email.com');
Fixtures::add('password', 'password');

1
tests/_data/dump.sql Normal file
View File

@ -0,0 +1 @@
/* Replace this file with actual dump of your database */

View File

@ -0,0 +1,56 @@
<?php
use Codeception\Util\Fixtures;
/**
* 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 \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
*
* @SuppressWarnings(PHPMD)
*/
class AcceptanceTester extends \Codeception\Actor
{
use _generated\AcceptanceTesterActions;
/**
* Define custom actions here
*/
function checkIfLogin(\AcceptanceTester $I)
{
//if ($I->loadSessionSnapshot('login')) return;
$I->amOnPage('/login');
$I->fillField(['name' => 'email'], Fixtures::get('username'));
$I->fillField(['name' => 'password'], Fixtures::get('password'));
$I->click('Let\'s go');
//$I->saveSessionSnapshot('login');
}
function selectDataPicker(\AcceptanceTester $I, $element, $date = 'now')
{
$_date = date('Y, m, d', strtotime($date));
$I->executeJS(sprintf('$(\'%s\').datepicker(\'update\', new Date(%s))', $element, $_date));
}
function selectDropdown(\AcceptanceTester $I, $option, $dropdownSelector)
{
$I->click($dropdownSelector);
$I->click(sprintf('ul.typeahead li[data-value="%s"]', $option));
}
function selectDropdownRow(\AcceptanceTester $I, $option, $dropdownSelector)
{
$I->click("$dropdownSelector span.dropdown-toggle");
$I->click("$dropdownSelector ul li:nth-child($option)");
}
}

View File

@ -0,0 +1,26 @@
<?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 \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
*
* @SuppressWarnings(PHPMD)
*/
class FunctionalTester extends \Codeception\Actor
{
use _generated\FunctionalTesterActions;
/**
* Define custom actions here
*/
}

View File

@ -0,0 +1,9 @@
<?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
{
}

View File

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

View File

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

View File

@ -0,0 +1,26 @@
<?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 \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
*
* @SuppressWarnings(PHPMD)
*/
class UnitTester extends \Codeception\Actor
{
use _generated\UnitTesterActions;
/**
* Define custom actions here
*/
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
<?php //[STAMP] 36f7a8f691a15285be178f5636f52285
namespace _generated;
// This class was automatically generated by build task
// You should not change it manually as it will be overwritten on next build
// @codingStandardsIgnoreFile
use Helper\Functional;
trait FunctionalTesterActions
{
/**
* @return \Codeception\Scenario
*/
abstract protected function getScenario();
}

View File

@ -0,0 +1,348 @@
<?php //[STAMP] 411f8e49789d4aff7d24b72665b5df9f
namespace _generated;
// This class was automatically generated by build task
// You should not change it manually as it will be overwritten on next build
// @codingStandardsIgnoreFile
use Codeception\Module\Asserts;
use Helper\Unit;
trait UnitTesterActions
{
/**
* @return \Codeception\Scenario
*/
abstract protected function getScenario();
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that two variables are equal.
*
* @param $expected
* @param $actual
* @param string $message
*
* @return mixed
* @see \Codeception\Module\Asserts::assertEquals()
*/
public function assertEquals($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertEquals', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that two variables are not equal
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertNotEquals()
*/
public function assertNotEquals($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotEquals', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that two variables are same
*
* @param $expected
* @param $actual
* @param string $message
*
* @return mixed
* @see \Codeception\Module\Asserts::assertSame()
*/
public function assertSame($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertSame', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that two variables are not same
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertNotSame()
*/
public function assertNotSame($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotSame', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that actual is greater than expected
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertGreaterThan()
*/
public function assertGreaterThan($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThan', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* @deprecated
* @see \Codeception\Module\Asserts::assertGreaterThen()
*/
public function assertGreaterThen($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThen', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that actual is greater or equal than expected
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertGreaterThanOrEqual()
*/
public function assertGreaterThanOrEqual($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThanOrEqual', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* @deprecated
* @see \Codeception\Module\Asserts::assertGreaterThenOrEqual()
*/
public function assertGreaterThenOrEqual($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertGreaterThenOrEqual', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that actual is less than expected
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertLessThan()
*/
public function assertLessThan($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertLessThan', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that actual is less or equal than expected
*
* @param $expected
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertLessThanOrEqual()
*/
public function assertLessThanOrEqual($expected, $actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertLessThanOrEqual', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that haystack contains needle
*
* @param $needle
* @param $haystack
* @param string $message
* @see \Codeception\Module\Asserts::assertContains()
*/
public function assertContains($needle, $haystack, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertContains', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that haystack doesn't contain needle.
*
* @param $needle
* @param $haystack
* @param string $message
* @see \Codeception\Module\Asserts::assertNotContains()
*/
public function assertNotContains($needle, $haystack, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotContains', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that string match with pattern
*
* @param string $pattern
* @param string $string
* @param string $message
* @see \Codeception\Module\Asserts::assertRegExp()
*/
public function assertRegExp($pattern, $string, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertRegExp', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that string not match with pattern
*
* @param string $pattern
* @param string $string
* @param string $message
* @see \Codeception\Module\Asserts::assertNotRegExp()
*/
public function assertNotRegExp($pattern, $string, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotRegExp', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that variable is empty.
*
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertEmpty()
*/
public function assertEmpty($actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertEmpty', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that variable is not empty.
*
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertNotEmpty()
*/
public function assertNotEmpty($actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotEmpty', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that variable is NULL
*
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertNull()
*/
public function assertNull($actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNull', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that variable is not NULL
*
* @param $actual
* @param string $message
* @see \Codeception\Module\Asserts::assertNotNull()
*/
public function assertNotNull($actual, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotNull', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that condition is positive.
*
* @param $condition
* @param string $message
* @see \Codeception\Module\Asserts::assertTrue()
*/
public function assertTrue($condition, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertTrue', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks that condition is negative.
*
* @param $condition
* @param string $message
* @see \Codeception\Module\Asserts::assertFalse()
*/
public function assertFalse($condition, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFalse', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks if file exists
*
* @param string $filename
* @param string $message
* @see \Codeception\Module\Asserts::assertFileExists()
*/
public function assertFileExists($filename, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileExists', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Checks if file doesn't exist
*
* @param string $filename
* @param string $message
* @see \Codeception\Module\Asserts::assertFileNotExists()
*/
public function assertFileNotExists($filename, $message = null) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertFileNotExists', func_get_args()));
}
/**
* [!] Method is generated. Documentation taken from corresponding module.
*
* Fails the test with message.
*
* @param $message
* @see \Codeception\Module\Asserts::fail()
*/
public function fail($message) {
return $this->getScenario()->runStep(new \Codeception\Step\Action('fail', func_get_args()));
}
}

View File

@ -0,0 +1,24 @@
# 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.
class_name: AcceptanceTester
modules:
enabled:
- WebDriver:
url: 'http://ninja.dev/'
host: 127.0.0.1
window_size: 1024x768
wait: 5
browser: phantomjs
capabilities:
unexpectedAlertBehaviour: 'accept'
webStorageEnabled: true
- Db:
dsn: 'mysql:dbname=ninja;host=localhost;'
user: 'ninja'
password: 'ninja'
dump: tests/_data/dump.sql
- \Helper\Acceptance

View File

@ -0,0 +1,96 @@
<?php
$I = new AcceptanceTester($scenario);
$I->wantTo('Test all pages load');
$I->amOnPage('/login');
//$I->see(trans('texts.forgot_password'));
// Login as test user
$I->fillField(['name' => 'email'], 'hillelcoren@gmail.com');
$I->fillField(['name' => 'password'], '4uejs%2ksl#271df');
$I->click('Let\'s go');
$I->see('Dashboard');
// Top level navigation
$I->amOnPage('/dashboard');
$I->see('Total Revenue');
$I->amOnPage('/clients');
$I->see('Clients', 'li');
$I->amOnPage('/clients/create');
$I->see('Clients', 'li');
$I->see('Create');
$I->amOnPage('/credits');
$I->see('Credits', 'li');
$I->amOnPage('/credits/create');
$I->see('Credits', 'li');
$I->see('Create');
$I->amOnPage('/tasks');
$I->see('Tasks', 'li');
$I->amOnPage('/tasks/create');
$I->see('Tasks', 'li');
$I->see('Create');
$I->amOnPage('/invoices');
$I->see('Invoices', 'li');
$I->amOnPage('/invoices/create');
$I->see('Invoices', 'li');
$I->see('Create');
$I->amOnPage('/quotes');
$I->see('Quotes', 'li');
$I->amOnPage('/quotes/create');
$I->see('Quotes', 'li');
$I->see('Create');
$I->amOnPage('/payments');
$I->see('Payments', 'li');
$I->amOnPage('/payments/create');
$I->see('Payments', 'li');
$I->see('Create');
// Settings pages
$I->amOnPage('/company/details');
$I->see('Details');
$I->amOnPage('/gateways/create');
$I->see('Add Gateway');
$I->amOnPage('/company/products');
$I->see('Product Settings');
$I->amOnPage('/company/import_export');
$I->see('Import');
$I->amOnPage('/company/advanced_settings/invoice_settings');
$I->see('Invoice Fields');
$I->amOnPage('/company/advanced_settings/invoice_design');
$I->see('Invoice Design');
$I->amOnPage('/company/advanced_settings/email_templates');
$I->see('Invoice Email');
$I->amOnPage('/company/advanced_settings/charts_and_reports');
$I->see('Data Visualizations');
$I->amOnPage('/company/advanced_settings/user_management');
$I->see('Add User');
//try to logout
$I->click('#myAccountButton');
$I->see('Log Out');
$I->click('Log Out');
// Miscellaneous pages
$I->amOnPage('/terms');
$I->see('Terms');

View File

@ -0,0 +1,103 @@
<?php
use \AcceptanceTester;
use Faker\Factory;
class ChartsAndReportsCest
{
private $faker;
public function _before(AcceptanceTester $I)
{
$I->checkIfLogin($I);
$this->faker = Factory::create();
}
public function _after(AcceptanceTester $I)
{
}
// tests
public function updateChartsAndReportsPage(AcceptanceTester $I)
{
$faker = Faker\Factory::create();
$I->wantTo("Run the report");
$I->amOnPage('/company/advanced_settings/charts_and_reports');
/*
$format = 'M d,Y';
$start_date = date ( $format, strtotime ( '-7 day' . $format));
$I->fillField(['name' => 'start_date'],$start_date);
$I->fillField(['name' => 'start_date'], 'April 15, 2015');
$I->fillField(['name' => 'end_date'], date('M d,Y'));
$I->fillField(['name' => 'end_date'], 'August 29, 2015');
*/
$I->checkOption(['name' => 'enable_report']);
$I->selectOption("#report_type", 'Client');
$I->checkOption(['name' => 'enable_chart']);
$rand = ['DAYOFYEAR', 'WEEK', 'MONTH'];
$I->selectOption("#group_by", $rand[array_rand($rand)]);
$rand = ['Bar', 'Line'];
$I->selectOption("#chart_type", $rand[array_rand($rand)]);
$I->click('Run');
$I->see('Start Date');
}
/*
public function showDataVisualization(AcceptanceTester $I) {
$I->wantTo('Display pdf data');
$I->amOnPage('/company/advanced_settings/data_visualizations');
$optionTest = "1"; // This is the option to test!
$I->selectOption('#groupBySelect', $optionTest);
$models = ['Client', 'Invoice', 'Product'];
//$all = Helper::getRandom($models[array_rand($models)], 'all');
$all = Helper::getRandom('Client', 'all');
$labels = $this->getLabels($optionTest);
$all_items = true;
$I->seeElement('div.svg-div svg g:nth-child(2)');
for ($i = 0; $i < count($labels); $i++) {
$text = $I->grabTextFrom('div.svg-div svg g:nth-child('.($i+2).') text');
//$I->seeInField('div.svg-div svg g:nth-child('.($i+2).') text', $labels[$i]);
if (!in_array($text, $labels)) {
$all_items = false;
break;
}
}
if (!$all_items) {
$I->see('Fail', 'Fail');
}
}
private function getLabels($option) {
$invoices = \App\Models\Invoice::where('user_id', '1')->get();
$clients = [];
foreach ($invoices as $invoice) {
$clients[] = \App\Models\Client::where('public_id', $invoice->client_id)->get();
}
$clientNames = [];
foreach ($clients as $client) {
$clientNames[] = $client[0]->name;
}
return $clientNames;
}
*/
}

View File

@ -0,0 +1,103 @@
<?php
use \AcceptanceTester;
use Faker\Factory;
use Codeception\Util\Fixtures;
class ClientCest
{
/**
* @var \Faker\Generator
*/
private $faker;
public function _before(AcceptanceTester $I)
{
$I->checkIfLogin($I);
$this->faker = Factory::create();
}
public function createClient(AcceptanceTester $I)
{
$I->wantTo('Create a client');
//Organization
$I->amOnPage('/clients/create');
$I->fillField(['name' => 'name'], $name = $this->faker->name);
$I->fillField(['name' => 'id_number'], rand(0, 10000));
$I->fillField(['name' => 'vat_number'], rand(0, 10000));
$I->fillField(['name' => 'website'], $this->faker->url);
$I->fillField(['name' => 'work_phone'], $this->faker->phoneNumber);
//Contacts
$I->fillField(['name' => 'first_name'], $this->faker->firstName);
$I->fillField(['name' => 'last_name'], $this->faker->lastName);
$I->fillField(['name' => 'email'], $this->faker->companyEmail);
$I->fillField(['name' => 'phone'], $this->faker->phoneNumber);
//Additional Contact
//$I->click('Add contact +');
//$I->fillField('.form-group:nth-child(6) #first_name', $this->faker->firstName);
//$I->fillField('.form-group:nth-child(7) #last_name', $this->faker->lastName);
//$I->fillField('.form-group:nth-child(8) #email1', $this->faker->companyEmail);
//$I->fillField('.form-group:nth-child(9) #phone', $this->faker->phoneNumber);
//Address
$I->see('Street');
$I->fillField(['name' => 'address1'], $this->faker->streetAddress);
$I->fillField(['name' => 'address2'], $this->faker->streetAddress);
$I->fillField(['name' => 'city'], $this->faker->city);
$I->fillField(['name' => 'state'], $this->faker->state);
$I->fillField(['name' => 'postal_code'], $this->faker->postcode);
//$I->executeJS('$(\'input[name="country_id"]\').val('. Helper::getRandom('Country').')');
//Additional Info
//$I->selectOption(['name' => 'currency_id'], Helper::getRandom('Currency'));;
//$I->selectOption(['name' => 'payment_terms'], Helper::getRandom('PaymentTerm', 'num_days'));
//$I->selectOption(['name' => 'size_id'], Helper::getRandom('Size'));
//$I->selectOption(['name' => 'industry_id'], Helper::getRandom('Industry'));
//$I->fillField(['name' => 'private_notes'], 'Private Notes');
$I->click('Save');
$I->see($name);
}
public function editClient(AcceptanceTester $I)
{
$I->wantTo('Edit a client');
//$id = Helper::getRandom('Client', 'public_id');
//$url = sprintf('/clients/%d/edit', $id);
$url = '/clients/1/edit';
$I->amOnPage($url);
$I->seeCurrentUrlEquals($url);
//update fields
$name = $this->faker->firstName;
$I->fillField(['name' => 'name'], $name);
$I->click('Save');
$I->see($name);
}
/*
public function deleteClient(AcceptanceTester $I)
{
$I->wantTo('delete a client');
$I->amOnPage('/clients');
$I->seeCurrentUrlEquals('/clients');
$I->executeJS(sprintf('deleteEntity(%s)', $id = Helper::getRandom('Client', 'public_id')));
$I->acceptPopup();
//check if client was removed from database
$I->wait(5);
$I->seeInDatabase('clients', ['public_id' => $id, 'is_deleted' => true]);
}
*/
}

View File

@ -0,0 +1,41 @@
<?php
use \AcceptanceTester;
use App\Models\Credit;
use Faker\Factory;
use Codeception\Util\Fixtures;
class CreditCest
{
private $faker;
public function _before(AcceptanceTester $I)
{
$I->checkIfLogin($I);
$this->faker = Factory::create();
}
public function create(AcceptanceTester $I)
{
$note = $this->faker->catchPhrase;
$clientName = $I->grabFromDatabase('clients', 'name');
$I->wantTo('Create a credit');
$I->amOnPage('/credits/create');
$I->selectDropdown($I, $clientName, '.client-select .dropdown-toggle');
$I->fillField(['name' => 'amount'], rand(50, 200));
$I->fillField(['name' => 'private_notes'], $note);
$I->selectDataPicker($I, '#credit_date', 'now + 1 day');
$I->click('Save');
$I->see('Successfully created credit');
$I->seeInDatabase('credits', array('private_notes' => $note));
$I->amOnPage('/credits');
$I->seeCurrentUrlEquals('/credits');
$I->see($clientName);
}
}

View File

@ -0,0 +1,30 @@
<?php
use \AcceptanceTester;
use Faker\Factory;
class GatewayCest
{
private $faker;
public function _before(AcceptanceTester $I)
{
$I->checkIfLogin($I);
$this->faker = Factory::create();
}
// tests
public function create(AcceptanceTester $I)
{
$I->wantTo("create a gateway");
$I->amOnPage('/gateways/create');
$I->seeCurrentUrlEquals('/gateways/create');
$I->fillField(['name' => '23_apiKey'], $this->faker->swiftBicNumber);
$I->click('Save');
$I->see('Successfully created gateway');
$I->seeInDatabase('account_gateways', array('gateway_id' => 23));
}
}

View File

@ -0,0 +1,150 @@
<?php
use \AcceptanceTester;
use Faker\Factory;
class InvoiceCest
{
/**
* @var \Faker\Generator
*/
private $faker;
public function _before(AcceptanceTester $I)
{
$I->checkIfLogin($I);
$this->faker = Factory::create();
}
public function createInvoice(AcceptanceTester $I)
{
$clientName = $I->grabFromDatabase('clients', 'name');
$I->wantTo('create an invoice');
$I->amOnPage('/invoices/create');
$invoiceNumber = $I->grabAttributeFrom('#invoice_number', 'value');
$I->selectDropdown($I, $clientName, '.client_select .dropdown-toggle');
$I->selectDataPicker($I, '#invoice_date');
$I->selectDataPicker($I, '#due_date', '+ 15 day');
$I->fillField('#po_number', rand(100, 200));
$I->fillField('#discount', rand(0, 20));
$this->fillItems($I);
$I->click('#saveButton');
$I->wait(1);
$I->see($invoiceNumber);
}
public function createRecurringInvoice(AcceptanceTester $I)
{
$clientName = $I->grabFromDatabase('clients', 'name');
$I->wantTo('create a recurring invoice');
$I->amOnPage('/recurring_invoices/create');
$I->selectDropdown($I, $clientName, '.client_select .dropdown-toggle');
//$I->selectOption('#frequency_id', Helper::getRandom('Frequency'));
$I->selectDataPicker($I, '#start_date');
$I->selectDataPicker($I, '#end_date', '+ 1 week');
$I->fillField('#po_number', rand(100, 200));
$I->fillField('#discount', rand(0, 20));
$this->fillItems($I);
$I->executeJS('submitAction()');
$I->wait(1);
$I->see($clientName);
}
public function editInvoice(AcceptanceTester $I)
{
$I->wantTo('edit an invoice');
$I->amOnPage('/invoices/1/edit');
//change po_number with random number
$po_number = rand(100, 300);
$I->fillField('po_number', $po_number);
//save
$I->executeJS('submitAction()');
$I->wait(1);
//check if po_number was updated
$I->seeInDatabase('invoices', ['po_number' => $po_number]);
}
public function cloneInvoice(AcceptanceTester $I)
{
$I->wantTo('clone an invoice');
$I->amOnPage('invoices/1/clone');
$invoiceNumber = $I->grabAttributeFrom('#invoice_number', 'value');
$I->executeJS('submitAction()');
$I->wait(1);
$I->see($invoiceNumber);
}
/*
public function deleteInvoice(AcceptanceTester $I)
{
$I->wantTo('delete an invoice');
$I->amOnPage('/invoices');
$I->seeCurrentUrlEquals('/invoices');
//delete invoice
$I->executeJS(sprintf('deleteEntity(%d)', $id = Helper::getRandom('Invoice', 'public_id', ['is_quote' => 0])));
$I->acceptPopup();
$I->wait(5);
//check if invoice was removed
$I->seeInDatabase('invoices', ['public_id' => $id, 'is_deleted' => true]);
}
*/
/*
public function indexInvoice(AcceptanceTester $I)
{
$I->wantTo('list invoices');
$I->amOnPage('/invoices');
$I->seeCurrentUrlEquals('/invoices');
$random_invoice_number = Helper::getRandom('Invoice', 'invoice_number', [
'is_quote' => 0,
'is_recurring' => false
]);
if ($random_invoice_number) {
$I->wait(2);
$I->see($random_invoice_number);
}
}
*/
private function fillItems(AcceptanceTester $I, $max = 2)
{
for ($i = 1; $i <= $max; $i++) {
$row_selector = sprintf('table.invoice-table tbody tr:nth-child(%d) ', $i);
$product_key = $this->faker->text(10);
$description = $this->faker->text(80);
$unit_cost = $this->faker->randomFloat(2, 0, 100);
$quantity = $this->faker->randomDigitNotNull;
$I->fillField($row_selector.'#product_key', $product_key);
$I->fillField($row_selector.'textarea', $description);
$I->fillField($row_selector.'td:nth-child(4) input', $unit_cost);
$I->fillField($row_selector.'td:nth-child(5) input', $quantity);
}
}
}

View File

@ -0,0 +1,59 @@
<?php
require_once __DIR__ . '/../helpers/Helper.php';
use \AcceptanceTester;
use Faker\Factory;
class InvoiceDesignCest
{
private $faker;
public function _before(AcceptanceTester $I)
{
$I->checkIfLogin($I);
$this->faker = Factory::create();
}
public function _after(AcceptanceTester $I)
{
}
// tests
public function updateInvoiceDesign(AcceptanceTester $I)
{
$I->wantTo('Design my invoice');
$I->amOnPage('/company/advanced_settings/invoice_design');
$I->click('select#invoice_design_id');
$I->click('select#invoice_design_id option:nth-child(2)');
$I->fillField('#font_size', 10);
$I->click('#primary_color + .sp-replacer');
$I->executeJS('$("#primary_color").val("#7364b6")');
//$I->executeJS('$("#primary_color + .sp-replacer .sp-preview-inner").attr("style", "background-color: rgb(0,98,254);")');
$I->executeJS('$(".sp-container:nth-child(1) .sp-choose").click()');
$I->click('#secondary_color + .sp-replacer');
$I->executeJS('$("#secondary_color").val("#aa6709")');
//$I->executeJS('$("#secondary_color + .sp-replacer .sp-preview-inner").attr("style", "background-color: rgb(254,0,50);")');
$I->executeJS('$(".sp-container:nth-child(2) .sp-choose").click()');
$I->fillField(['name' => 'labels_item'], $this->faker->text(6));
$I->fillField(['name' => 'labels_description'], $this->faker->text(12));
$I->fillField(['name' => 'labels_unit_cost'], $this->faker->text(12));
$I->fillField(['name' => 'labels_quantity'], $this->faker->text(8));
$I->uncheckOption('#hide_quantity');
$I->checkOption('#hide_paid_to_date');
$I->click('Save');
$I->wait(3);
$I->seeInDatabase('accounts', ['font_size' => 10]);
}
}

View File

@ -0,0 +1,84 @@
<?php
use \AcceptanceTester;
use App\Models\Payment;
use Faker\Factory;
class PaymentCest
{
private $faker;
public function _before(AcceptanceTester $I)
{
$I->checkIfLogin($I);
$this->faker = Factory::create();
}
public function create(AcceptanceTester $I)
{
$clientName = $I->grabFromDatabase('clients', 'name');
$amount = rand(1, 30);
$I->wantTo("enter a payment");
$I->amOnPage('/payments/create');
$I->selectDropdown($I, $clientName, '.client-select .dropdown-toggle');
$I->selectDropdownRow($I, 1, '.invoice-select .combobox-container');
$I->fillField(['name' => 'amount'], $amount);
$I->selectDropdownRow($I, 1, 'div.panel-body div.form-group:nth-child(4) .combobox-container');
$I->selectDataPicker($I, '#payment_date', 'now + 1 day');
$I->fillField(['name' => 'transaction_reference'], $this->faker->text(12));
$I->click('Save');
$I->see('Successfully created payment');
$I->seeInDatabase('payments', ['amount' => number_format($amount, 2)]);
}
public function editPayment(AcceptanceTester $I)
{
$ref = $this->faker->text(12);
$I->wantTo("edit a payment");
$I->amOnPage('/payments/1/edit');
$I->selectDataPicker($I, '#payment_date', 'now + 2 day');
$I->fillField(['name' => 'transaction_reference'], $ref);
$I->click('Save');
$I->seeInDatabase('payments', ['transaction_reference' => $ref]);
}
public function listPayments(AcceptanceTester $I)
{
$I->wantTo("list payments");
$I->amOnPage('/payments');
$I->seeNumberOfElements('tbody tr[role=row]', [1, 10]);
}
/*
public function delete(AcceptanceTester $I)
{
$I->wantTo('delete a payment');
$I->amOnPage('/payments');
$I->seeCurrentUrlEquals('/payments');
$I->wait(3);
if ($num_payments = Payment::all()->count()) {
$row_rand = sprintf('tbody tr:nth-child(%d)', rand(1, $num_payments));
//show button
$I->executeJS(sprintf('$("%s div").css("visibility", "visible")', $row_rand));
//dropdown
$I->click($row_rand . ' button');
//click to delete button
$I->click($row_rand . ' ul li:nth-last-child(1) a');
$I->acceptPopup();
}
}
*/
}

View File

@ -0,0 +1,95 @@
<?php
use \AcceptanceTester;
use Faker\Factory;
class TaskCest
{
/**
* @var \Faker\Generator
*/
private $faker;
public function _before(AcceptanceTester $I)
{
$I->checkIfLogin($I);
$this->faker = Factory::create();
}
public function createTimerTask(AcceptanceTester $I)
{
$description = $this->faker->text(100);
$I->wantTo('create a timed task');
$I->amOnPage('/tasks/create');
$I->seeCurrentUrlEquals('/tasks/create');
$I->fillField('#description', $description);
$I->click('Start');
$I->wait(rand(2, 5));
$I->click('Stop');
$I->click('Save');
$I->seeInDatabase('tasks', ['description' => $description]);
}
public function createManualTask(AcceptanceTester $I)
{
$description = $this->faker->text(100);
$I->wantTo('create a manual task');
$I->amOnPage('/tasks/create');
$I->seeCurrentUrlEquals('/tasks/create');
$I->selectOption('#task_type3', 'Manual');
$I->fillField('#description', $description);
$I->click('Save');
$I->seeInDatabase('tasks', ['description' => $description]);
}
public function editTask(AcceptanceTester $I)
{
$description = $this->faker->text(100);
$I->wantTo('edit a task');
$I->amOnPage('/tasks/1/edit');
$I->seeCurrentUrlEquals('/tasks/1/edit');
$I->fillField('#description', $description);
$I->click('Save');
$I->seeInDatabase('tasks', ['description' => $description]);
}
public function listTasks(AcceptanceTester $I)
{
$I->wantTo("list tasks");
$I->amOnPage('/tasks');
$I->seeNumberOfElements('tbody tr[role=row]', [1, 10]);
}
/*
public function deleteTask(AcceptanceTester $I)
{
$I->wantTo('delete a Task');
$I->amOnPage('/tasks');
$task_id = Helper::getRandom('Task', 'public_id');
//delete task
$I->executeJS(sprintf('deleteEntity(%d)', $task_id));
$I->acceptPopup();
//check if Task was delete
$I->wait(2);
$I->seeInDatabase('tasks', ['public_id' => $task_id, 'is_deleted' => true]);
}
*/
}

View File

@ -0,0 +1,2 @@
<?php
// Here you can initialize variables that will be available to your tests

View File

@ -0,0 +1,11 @@
# Codeception Test Suite Configuration
#
# Suite for functional (integration) tests
# Emulate web requests and make application process them
# Include one of framework modules (Symfony2, Yii2, Laravel5) to use it
class_name: FunctionalTester
modules:
enabled:
# add framework module here
- \Helper\Functional

View File

@ -0,0 +1,2 @@
<?php
// Here you can initialize variables that will be available to your tests

9
tests/unit.suite.yml Normal file
View File

@ -0,0 +1,9 @@
# Codeception Test Suite Configuration
#
# Suite for unit (internal) tests.
class_name: UnitTester
modules:
enabled:
- Asserts
- \Helper\Unit

View File

@ -0,0 +1,2 @@
<?php
// Here you can initialize variables that will be available to your tests