php artisan serve and dusk testing (#9422)

* php artisan serve and dusk testing

* Fix style

* move if into, in case we need to have different configs

* fix travis yml

* Add missing folders files

* Try to fixup Travis-ci

* revert variable, change check

* skip browser tests for phpunit runs
set up env correctly

* maybe bg is needed

* attempt to fix env

* install Chrome

* Update tests
fix migrations

* Move pylint to python2

* use testing .env

* Running chrome on port 9515 conflicts with the instance started by the tests.  It is probably not needed.

* suppress some artisan serve output

* remove the unused updater
This commit is contained in:
Tony Murray 2019-02-14 09:06:10 -06:00 committed by GitHub
parent 108348e93f
commit 63de34e295
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 363 additions and 20 deletions

5
.env.dusk.testing Normal file
View File

@ -0,0 +1,5 @@
APP_URL=http://localhost:8000
APP_KEY=base64:FSjpEaK3F9HnO40orj7FlbRI0loi1vtB3dVBcB9XaDk=
APP_ENV=testing
APP_DEBUG=true
#DB_CONNECTION=memory

View File

@ -1,14 +1,19 @@
sudo: required
language: php
addons:
chrome: stable
services:
- mysql
env:
global:
APP_ENV=testing
matrix:
fast_finish: true
include:
- php: 7.3
env: SKIP_STYLE_CHECK=1
- php: 7.2
env: SKIP_UNIT_CHECK=1
env: SKIP_UNIT_CHECK=1 BROWSER_TEST=1
- php: 7.1
env: SKIP_STYLE_CHECK=1 EXECUTE_BUILD_DOCS=true
@ -25,18 +30,23 @@ before_install:
- cp tests/config/config.test.php config.php
install:
- composer install --prefer-dist --no-interaction
- pip install --user snmpsim pylint mysql-python
- travis_retry composer install --no-interaction --prefer-dist --no-suggest
- pip3 install --user snmpsim
- pip install --user mysql-python pylint
after_failure:
- tail /tmp/snmpsimd.log
before_script:
- test -z "$BROWSER_TEST" || php artisan serve --env=dusk.testing 2>/dev/null &
script:
- set -e
- export FILES=$(git diff --diff-filter=d --name-only master | tr '\n' ' '|sed 's/,*$//g')
- php scripts/pre-commit.php -q -l
- php scripts/pre-commit.php -q -s
- php scripts/pre-commit.php -u --db --snmpsim --fail-fast
- test -z "$BROWSER_TEST" || php artisan dusk
- bash -n daily.sh
- pylint -E poller-wrapper.py discovery-wrapper.py
- bash scripts/deploy-docs.sh

35
app/Application.php Normal file
View File

@ -0,0 +1,35 @@
<?php
/**
* Application.php
*
* Extension of base application class
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App;
class Application extends \Illuminate\Foundation\Application
{
public function publicPath()
{
// override the public path
return $this->basePath.DIRECTORY_SEPARATOR.'html';
}
}

View File

@ -11,7 +11,7 @@
|
*/
$app = new Illuminate\Foundation\Application(
$app = new App\Application(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

View File

@ -52,18 +52,19 @@
"doctrine/dbal": "^2.9"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.2",
"barryvdh/laravel-ide-helper": "^2.5",
"beyondcode/laravel-dump-server": "^1.0",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"jakub-onderka/php-console-highlighter": "*",
"jakub-onderka/php-parallel-lint": "*",
"justinrainbow/json-schema": "^5.2",
"laravel/dusk": "^5.0",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^2.0",
"phpunit/phpunit": "^7.0",
"squizlabs/php_codesniffer": "^2.9.1",
"jakub-onderka/php-parallel-lint": "*",
"jakub-onderka/php-console-highlighter": "*",
"barryvdh/laravel-ide-helper": "^2.5",
"barryvdh/laravel-debugbar": "^3.2",
"justinrainbow/json-schema": "^5.2"
"squizlabs/php_codesniffer": "^2.9.1"
},
"suggest": {
"ext-memcached": "Required if you utilize distributed polling",

123
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "89499eb92892d605e890132cd59dfd9d",
"content-hash": "e914d23478621df28362563f06165c49",
"packages": [
{
"name": "amenadiel/jpgraph",
@ -5078,6 +5078,66 @@
],
"time": "2017-07-22T11:58:36+00:00"
},
{
"name": "facebook/webdriver",
"version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/facebook/php-webdriver.git",
"reference": "bd8c740097eb9f2fc3735250fc1912bc811a954e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/bd8c740097eb9f2fc3735250fc1912bc811a954e",
"reference": "bd8c740097eb9f2fc3735250fc1912bc811a954e",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"ext-zip": "*",
"php": "^5.6 || ~7.0",
"symfony/process": "^2.8 || ^3.1 || ^4.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.0",
"jakub-onderka/php-parallel-lint": "^0.9.2",
"php-coveralls/php-coveralls": "^2.0",
"php-mock/php-mock-phpunit": "^1.1",
"phpunit/phpunit": "^5.7",
"sebastian/environment": "^1.3.4 || ^2.0 || ^3.0",
"squizlabs/php_codesniffer": "^2.6",
"symfony/var-dumper": "^3.3 || ^4.0"
},
"suggest": {
"ext-SimpleXML": "For Firefox profile creation"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-community": "1.5-dev"
}
},
"autoload": {
"psr-4": {
"Facebook\\WebDriver\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"description": "A PHP client for Selenium WebDriver",
"homepage": "https://github.com/facebook/php-webdriver",
"keywords": [
"facebook",
"php",
"selenium",
"webdriver"
],
"time": "2018-05-16T17:37:13+00:00"
},
{
"name": "filp/whoops",
"version": "2.3.1",
@ -5351,6 +5411,67 @@
],
"time": "2019-01-14T23:55:14+00:00"
},
{
"name": "laravel/dusk",
"version": "v5.0.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/dusk.git",
"reference": "590480abf75bf052873d7ff16deb5736cf749a55"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/dusk/zipball/590480abf75bf052873d7ff16deb5736cf749a55",
"reference": "590480abf75bf052873d7ff16deb5736cf749a55",
"shasum": ""
},
"require": {
"facebook/webdriver": "^1.3",
"illuminate/console": "~5.7.0|~5.8.0",
"illuminate/support": "~5.7.0|~5.8.0",
"nesbot/carbon": "^1.20|^2.0",
"php": ">=7.1.0",
"symfony/console": "^4.0",
"symfony/process": "^4.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^7.0|^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
},
"laravel": {
"providers": [
"Laravel\\Dusk\\DuskServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Laravel\\Dusk\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Laravel Dusk provides simple end-to-end testing and browser automation.",
"keywords": [
"laravel",
"testing",
"webdriver"
],
"time": "2019-02-12T14:17:11+00:00"
},
{
"name": "maximebf/debugbar",
"version": "v1.15.0",

View File

@ -94,6 +94,12 @@ return [
'prefix_indexes' => true,
],
'memory' => [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
]
],
/*

View File

@ -16,14 +16,27 @@
use Carbon\Carbon;
use LibreNMS\Util\IPv4;
$factory->define(App\User::class, function (Faker\Generator $faker) {
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
static $password;
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'username' => $faker->unique()->userName,
'realname' => $faker->name,
'email' => $faker->safeEmail,
'password' => $password ?: $password = bcrypt('secret'),
'remember_token' => str_random(10),
'level' => 1,
];
});
$factory->state(App\Models\User::class, 'admin', function ($faker) {
return [
'level' => '10',
];
});
$factory->state(App\Models\User::class, 'read', function ($faker) {
return [
'level' => '5',
];
});

View File

@ -29,6 +29,6 @@ class CreateAlertSchedulablesTable extends Migration
*/
public function down()
{
Schema::drop('alert_schedule_items');
Schema::drop('alert_schedulables');
}
}

View File

@ -27,7 +27,7 @@ class AddForeignKeysToSensorsToStateIndexesTable extends Migration
public function down()
{
Schema::table('sensors_to_state_indexes', function (Blueprint $table) {
$table->dropForeign('sensors_to_state_indexes_ibfk_2');
$table->dropForeign('sensors_to_state_indexes_ibfk_1');
$table->dropForeign('sensors_to_state_indexes_sensor_id_foreign');
});
}

View File

@ -23,6 +23,7 @@
</testsuites>
<groups>
<exclude>
<group>browser</group>
<group>mibs</group>
</exclude>
</groups>

View File

@ -39,7 +39,7 @@
</div>
<div class="form-group">
<div class="col-md-12">
<button type="submit" class="btn btn-primary btn-block" name="submit" type="submit">
<button type="submit" id="login" class="btn btn-primary btn-block" name="submit" type="submit">
<i class="fa fa-btn fa-sign-in"></i> @lang('Login')
</button>
</div>

View File

@ -14,8 +14,8 @@ $uri = urldecode(
// This file allows us to emulate Apache's "mod_rewrite" functionality from the
// built-in PHP web server. This provides a convenient way to test a Laravel
// application without having installed a "real" web server software here.
if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
if ($uri !== '/' && file_exists(__DIR__.'/html'.$uri)) {
return false;
}
require_once __DIR__.'/public/index.php';
require_once __DIR__.'/html/index.php';

View File

@ -0,0 +1,40 @@
<?php
namespace LibreNMS\Tests\Browser;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use LibreNMS\Tests\Browser\Pages\LoginPage;
use LibreNMS\Tests\DuskTestCase;
/**
* Class LoginTest
* @package LibreNMS\Tests\Browser
* @group browser
*/
class LoginTest extends DuskTestCase
{
use DatabaseMigrations;
/**
* @throws \Throwable
*/
public function testUserCanLogin()
{
$this->browse(function (Browser $browser) {
$password = 'some_password';
$user = factory(User::class)->create([
'password' => password_hash($password, PASSWORD_DEFAULT)
]);
$browser->visit(new LoginPage())
->type('username', $user->username)
->type('password', $password)
->press('#login')
->assertPathIs('/');
$user->delete();
});
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace LibreNMS\Tests\Browser\Pages;
use Laravel\Dusk\Browser;
class LoginPage extends Page
{
/**
* Get the URL for the page.
*
* @return string
*/
public function url()
{
return '/login';
}
/**
* Assert that the browser is on the page.
*
* @param Browser $browser
* @return void
*/
public function assert(Browser $browser)
{
$browser->assertPathIs($this->url());
}
/**
* Get the element shortcuts for the page.
*
* @return array
*/
public function elements()
{
return [
'@element' => '#selector',
];
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace LibreNMS\Tests\Browser\Pages;
use Laravel\Dusk\Page as BasePage;
abstract class Page extends BasePage
{
/**
* Get the global element shortcuts for the site.
*
* @return array
*/
public static function siteElements()
{
return [
'@element' => '#selector',
];
}
}

5
tests/Browser/console/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

5
tests/Browser/screenshots/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

40
tests/DuskTestCase.php Normal file
View File

@ -0,0 +1,40 @@
<?php
namespace LibreNMS\Tests;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Laravel\Dusk\TestCase as BaseTestCase;
abstract class DuskTestCase extends BaseTestCase
{
use CreatesApplication;
/**
* Prepare for Dusk test execution.
*
* @beforeClass
* @return void
*/
public static function prepare()
{
static::startChromeDriver();
}
/**
* Create the RemoteWebDriver instance.
*
* @return \Facebook\WebDriver\Remote\RemoteWebDriver
*/
protected function driver()
{
return RemoteWebDriver::create('http://localhost:9515', DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY,
(new ChromeOptions)->addArguments([
'--disable-gpu',
'--headless'
])
));
}
}