Remove dusk tests, they're not used

This commit is contained in:
DaneEveritt 2022-05-04 20:41:32 -04:00
parent 66da520e11
commit ab37ee8633
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
19 changed files with 2 additions and 845 deletions

View file

@ -1,26 +0,0 @@
APP_ENV=local
APP_DEBUG=false
APP_KEY=NDWgIKKi9ovNK1PXZpzfNVSBdfCXGb5i
APP_JWT_KEY=test1234
APP_TIMEZONE=America/Los_Angeles
APP_URL=http://pterodactyl.local
CACHE_DRIVER=file
SESSION_DRIVER=file
HASHIDS_SALT=IqRr0g82tCTeuyxGs8RV
HASHIDS_LENGTH=8
MAIL_DRIVER=log
MAIL_FROM=support@pterodactyl.io
QUEUE_DRIVER=array
APP_SERVICE_AUTHOR=testing@pterodactyl.io
MAIL_FROM_NAME="Pterodactyl Panel"
RECAPTCHA_ENABLED=false
DB_CONNECTION=testing
TESTING_DB_HOST=192.168.1.202
TESTING_DB_DATABASE=panel_test
TESTING_DB_USERNAME=panel_test
TESTING_DB_PASSWORD=Test1234

View file

@ -33,7 +33,7 @@ jobs:
- name: Create release archive - name: Create release archive
run: | run: |
rm -rf node_modules/ test/ codecov.yml CODE_OF_CONDUCT.md CONTRIBUTING.md phpunit.dusk.xml phpunit.xml Vagrantfile rm -rf node_modules/ test/ codecov.yml CODE_OF_CONDUCT.md CONTRIBUTING.md phpunit.xml Vagrantfile
tar -czf panel.tar.gz * .env.example .eslintignore .eslintrc.yml .babel-plugin-macrosrc.js tar -czf panel.tar.gz * .env.example .eslintignore .eslintrc.yml .babel-plugin-macrosrc.js
- name: Extract changelog - name: Extract changelog

1
.gitignore vendored
View file

@ -1,7 +1,6 @@
/vendor /vendor
*.DS_Store* *.DS_Store*
!.env.ci !.env.ci
!.env.dusk
!.env.example !.env.example
.env* .env*
.vagrant/* .vagrant/*

View file

@ -47,7 +47,6 @@
"fakerphp/faker": "^1.19", "fakerphp/faker": "^1.19",
"friendsofphp/php-cs-fixer": "^3.8", "friendsofphp/php-cs-fixer": "^3.8",
"itsgoingd/clockwork": "^5.1", "itsgoingd/clockwork": "^5.1",
"laravel/dusk": "^6.23",
"mockery/mockery": "^1.5", "mockery/mockery": "^1.5",
"nunomaduro/collision": "^5.11", "nunomaduro/collision": "^5.11",
"php-mock/php-mock-phpunit": "^2.6", "php-mock/php-mock-phpunit": "^2.6",

140
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "75eb69604c51a9ac2dcdf4da1f6d24cb", "content-hash": "966e12710f76fb744c32e90103b9f823",
"packages": [ "packages": [
{ {
"name": "aws/aws-crt-php", "name": "aws/aws-crt-php",
@ -8218,79 +8218,6 @@
], ],
"time": "2022-04-12T21:35:47+00:00" "time": "2022-04-12T21:35:47+00:00"
}, },
{
"name": "laravel/dusk",
"version": "v6.23.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/dusk.git",
"reference": "41f6deb42ae42b9b7dae1c32c03cb35d365d3118"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/dusk/zipball/41f6deb42ae42b9b7dae1c32c03cb35d365d3118",
"reference": "41f6deb42ae42b9b7dae1c32c03cb35d365d3118",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-zip": "*",
"illuminate/console": "^6.0|^7.0|^8.0|^9.0",
"illuminate/support": "^6.0|^7.0|^8.0|^9.0",
"nesbot/carbon": "^2.0",
"php": "^7.2|^8.0",
"php-webdriver/webdriver": "^1.9.0",
"symfony/console": "^4.3|^5.0|^6.0",
"symfony/finder": "^4.3|^5.0|^6.0",
"symfony/process": "^4.3|^5.0|^6.0",
"vlucas/phpdotenv": "^3.0|^4.0|^5.2"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "^4.16|^5.17.1|^6.12.1|^7.0",
"phpunit/phpunit": "^7.5.15|^8.4|^9.0"
},
"suggest": {
"ext-pcntl": "Used to gracefully terminate Dusk when tests are running."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.x-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"
],
"support": {
"issues": "https://github.com/laravel/dusk/issues",
"source": "https://github.com/laravel/dusk/tree/v6.23.1"
},
"time": "2022-05-02T14:01:47+00:00"
},
{ {
"name": "mockery/mockery", "name": "mockery/mockery",
"version": "1.5.0", "version": "1.5.0",
@ -8862,71 +8789,6 @@
}, },
"time": "2020-02-08T15:44:47+00:00" "time": "2020-02-08T15:44:47+00:00"
}, },
{
"name": "php-webdriver/webdriver",
"version": "1.12.1",
"source": {
"type": "git",
"url": "https://github.com/php-webdriver/php-webdriver.git",
"reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/b27ddf458d273c7d4602106fcaf978aa0b7fe15a",
"reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-zip": "*",
"php": "^5.6 || ~7.0 || ^8.0",
"symfony/polyfill-mbstring": "^1.12",
"symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0 || ^6.0"
},
"replace": {
"facebook/webdriver": "*"
},
"require-dev": {
"ondram/ci-detector": "^2.1 || ^3.5 || ^4.0",
"php-coveralls/php-coveralls": "^2.4",
"php-mock/php-mock-phpunit": "^1.1 || ^2.0",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9",
"squizlabs/php_codesniffer": "^3.5",
"symfony/var-dumper": "^3.3 || ^4.0 || ^5.0 || ^6.0"
},
"suggest": {
"ext-SimpleXML": "For Firefox profile creation"
},
"type": "library",
"autoload": {
"files": [
"lib/Exception/TimeoutException.php"
],
"psr-4": {
"Facebook\\WebDriver\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.",
"homepage": "https://github.com/php-webdriver/php-webdriver",
"keywords": [
"Chromedriver",
"geckodriver",
"php",
"selenium",
"webdriver"
],
"support": {
"issues": "https://github.com/php-webdriver/php-webdriver/issues",
"source": "https://github.com/php-webdriver/php-webdriver/tree/1.12.1"
},
"time": "2022-05-03T12:16:34+00:00"
},
{ {
"name": "phpdocumentor/reflection-common", "name": "phpdocumentor/reflection-common",
"version": "2.2.0", "version": "2.2.0",

View file

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Browser Test Suite">
<directory suffix="Test.php">./tests/Browser</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
</phpunit>

View file

@ -1,122 +0,0 @@
<?php
namespace Pterodactyl\Tests\Browser;
use Laravel\Dusk\TestCase;
use BadMethodCallException;
use Pterodactyl\Models\User;
use Pterodactyl\Console\Kernel;
use Illuminate\Support\Facades\Hash;
use Illuminate\Database\Eloquent\Model;
use Pterodactyl\Tests\CreatesApplication;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
abstract class BrowserTestCase extends TestCase
{
use CreatesApplication;
/**
* The default password to use for new accounts.
*
* @var string
*/
protected static $userPassword = 'Password123';
/**
* Create a fresh database instance before each test class is initialized. This is different
* than the default DatabaseMigrations as it is only run when the class is setup. The trait
* provided by Laravel will run on EACH test function, slowing things down significantly.
*
* If you need to reset the DB between function runs just include the trait in that specific
* test. In most cases you probably wont need to do this, or can modify the test slightly to
* avoid the need to do so.
*/
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
$app = require __DIR__ . '/../../bootstrap/app.php';
/** @var \Pterodactyl\Console\Kernel $kernel */
$kernel = $app->make(Kernel::class);
$kernel->bootstrap();
$kernel->call('migrate:fresh');
}
/**
* Setup tests.
*/
protected function setUp(): void
{
// Don't accidentally run the migrations aganist the non-testing database. Ask me
// how many times I've accidentally dropped my database...
if (env('DB_CONNECTION') !== 'testing') {
throw new BadMethodCallException('Cannot call browser tests using the non-testing database connection.');
}
parent::setUp();
// Gotta unset this to continue avoiding issues with the validation.
Model::unsetEventDispatcher();
}
/**
* Create the RemoteWebDriver instance.
*
* @return \Facebook\WebDriver\Remote\RemoteWebDriver
*/
protected function driver()
{
$options = (new ChromeOptions())->addArguments([
'--disable-gpu',
'--disable-infobars',
]);
return RemoteWebDriver::create(
'http://host.pterodactyl.local:4444/wd/hub',
DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY,
$options
)
);
}
/**
* Return an instance of the browser to be used for tests.
*
* @param \Facebook\WebDriver\Remote\RemoteWebDriver $driver
*
* @return \Pterodactyl\Tests\Browser\PterodactylBrowser
*/
protected function newBrowser($driver): PterodactylBrowser
{
return new PterodactylBrowser($driver);
}
/**
* Tear down the test and delete all cookies from the browser instance to address
* instances where the test would be kicked over to the login page.
*/
protected function tearDown(): void
{
/** @var \Pterodactyl\Tests\Browser\PterodactylBrowser $browser */
foreach (static::$browsers as $browser) {
$browser->driver->manage()->deleteAllCookies();
}
parent::tearDown();
}
/**
* Return a user model to authenticate aganist and use in the tests.
*/
protected function user(array $attributes = []): User
{
return User::factory()->create(array_merge([
'password' => Hash::make(static::$userPassword),
], $attributes));
}
}

View file

@ -1,19 +0,0 @@
<?php
namespace Pterodactyl\Tests\Browser\Pages;
use Laravel\Dusk\Page;
abstract class BasePage extends Page
{
/**
* @return array
*/
public static function siteElements()
{
return [
'@@success' => '.alert.success[role="alert"]',
'@@error' => '.alert.error[role="alert"]',
];
}
}

View file

@ -1,41 +0,0 @@
<?php
namespace Pterodactyl\Tests\Browser\Pages\Dashboard;
use Pterodactyl\Tests\Browser\Pages\BasePage;
class AccountPage extends BasePage
{
/**
* @return string
*/
public function url()
{
return '/account';
}
/**
* @return array
*/
public function elements()
{
return array_merge(parent::elements(), [
'@email' => '#update-email-container #grid-email',
'@password' => '#update-email-container #grid-password[type="password"]',
'@submit' => '#update-email-container button[type="submit"]',
'@current_password' => '#change-password-container #grid-password-current[type="password"]',
'@new_password' => '#change-password-container #grid-password-new[type="password"]',
'@confirm_password' => '#change-password-container #grid-password-new-confirm[type="password"]',
'@submit_password' => '#change-password-container button[type="submit"]',
'@2fa_button' => '#grid-open-two-factor-modal',
'@2fa_modal' => '.modal-mask #configure-two-factor',
'@2fa_token' => '#configure-two-factor #container-enable-two-factor #grid-two-factor-token[type="number"]',
'@2fa_token_disable' => '#configure-two-factor #container-disable-two-factor #grid-two-factor-token-disable',
'@2fa_enable' => '#configure-two-factor #container-enable-two-factor button[type="submit"]',
'@2fa_disable' => '#configure-two-factor #container-disable-two-factor button.btn-red[type="submit"]',
'@2fa_cancel' => '#configure-two-factor #container-disable-two-factor button.btn-secondary',
]);
}
}

View file

@ -1,26 +0,0 @@
<?php
namespace Pterodactyl\Tests\Browser\Pages;
class LoginPage extends BasePage
{
public function url(): string
{
return '/auth/login';
}
public function elements()
{
return [
'@email' => '#grid-email',
'@username' => '#grid-username',
'@password' => '#grid-password',
'@loginButton' => '#grid-login-button',
'@submitButton' => 'button.btn.btn-jumbo[type="submit"]',
'@forgotPassword' => 'a[href="/auth/password"][aria-label="Forgot password"]',
'@goToLogin' => 'a[href="/auth/login"][aria-label="Go to login"]',
'@alertSuccess' => 'div[role="alert"].success > span.message',
'@alertDanger' => 'div[role="alert"].danger > span.message',
];
}
}

View file

@ -1,50 +0,0 @@
<?php
namespace Pterodactyl\Tests\Browser\Processes\Authentication;
use Pterodactyl\Tests\Browser\BrowserTestCase;
use Pterodactyl\Tests\Browser\Pages\LoginPage;
use Pterodactyl\Tests\Browser\PterodactylBrowser;
class ForgotPasswordProcessTest extends BrowserTestCase
{
/**
* Test that the password reset page works as expected and displays the expected
* success messages to the client when submitted.
*/
public function testResetPasswordWithInvalidAccount()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->visit(new LoginPage())
->assertSee(trans('auth.forgot_password.label'))
->click('@forgotPassword')
->waitForLocation('/auth/password')
->assertFocused('@email')
->assertSeeIn('.input-open > p.text-xs', trans('auth.forgot_password.label_help'))
->assertSeeIn('@submitButton', trans('auth.forgot_password.button'))
->type('@email', 'unassociated@example.com')
->assertSeeIn('@goToLogin', trans('auth.go_to_login'))
->press('@submitButton')
->waitForLocation('/auth/login')
->assertSeeIn('div[role="alert"].success > span.message', 'We have e-mailed your password reset link!')
->assertFocused('@username')
->assertValue('@username', 'unassociated@example.com');
});
}
/**
* Test that you can type in your email address and then click forgot password and have
* the email maintained on the new page.
*/
public function testEmailCarryover()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->visit(new LoginPage())
->type('@username', 'dane@example.com')
->click('@forgotPassword')
->waitForLocation('/auth/password')
->assertFocused('@email')
->assertValue('@email', 'dane@example.com');
});
}
}

View file

@ -1,83 +0,0 @@
<?php
namespace Pterodactyl\Tests\Browser\Processes\Authentication;
use Facebook\WebDriver\WebDriverKeys;
use Pterodactyl\Tests\Browser\BrowserTestCase;
use Pterodactyl\Tests\Browser\Pages\LoginPage;
use Pterodactyl\Tests\Browser\PterodactylBrowser;
class LoginProcessTest extends BrowserTestCase
{
private $user;
/**
* Setup tests.
*/
protected function setUp(): void
{
parent::setUp();
$this->user = $this->user();
}
/**
* Test that a user can login successfully using their email address.
*/
public function testLoginUsingEmail()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->visit(new LoginPage())
->waitFor('@username')
->type('@username', $this->user->email)
->type('@password', self::$userPassword)
->click('@loginButton')
->waitForReload()
->assertPathIs('/')
->assertAuthenticatedAs($this->user);
});
}
/**
* Test that a user can login successfully using their username.
*/
public function testLoginUsingUsername()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->visit(new LoginPage())
->waitFor('@username')
->type('@username', $this->user->username)
->type('@password', self::$userPassword)
->click('@loginButton')
->waitForReload()
->assertPathIs('/')
->assertAuthenticatedAs($this->user);
});
}
/**
* Test that entering the wrong password shows the expected error and then allows
* us to login without clearing the username field.
*/
public function testLoginWithErrors()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->logout()
->visit(new LoginPage())
->waitFor('@username')
->type('@username', $this->user->email)
->type('@password', 'invalid')
->click('@loginButton')
->waitFor('.alert.error')
->assertSeeIn('.alert.error', trans('auth.failed'))
->assertValue('@username', $this->user->email)
->assertValue('@password', '')
->assertFocused('@password')
->type('@password', self::$userPassword)
->keys('@password', [WebDriverKeys::ENTER])
->waitForReload()
->assertPathIs('/')
->assertAuthenticatedAs($this->user);
});
}
}

View file

@ -1,67 +0,0 @@
<?php
namespace Pterodactyl\Tests\Browser\Processes\Dashboard;
use Pterodactyl\Tests\Browser\PterodactylBrowser;
use Pterodactyl\Tests\Browser\Pages\Dashboard\AccountPage;
class AccountEmailProcessTest extends DashboardTestCase
{
/**
* Test that an email address can be changed successfully.
*/
public function testEmailCanBeChanged()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->loginAs($this->user)
->visit(new AccountPage())
->assertValue('@email', $this->user->email)
->type('@email', 'new.email@example.com')
->type('@password', 'Password123')
->click('@submit')
->waitFor('@@success')
->assertSeeIn('@@success', trans('dashboard/account.email.updated'))
->assertValue('@email', 'new.email@example.com');
$this->assertDatabaseHas('users', ['id' => $this->user->id, 'email' => 'new.email@example.com']);
});
}
/**
* Test that the validation error message shows up when an invalid email is entered.
*/
public function testInvalidEmailShowsErrors()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->loginAs($this->user)
->visit(new AccountPage())
->assertMissing('@email ~ .input-help.error')
->type('@email', 'admin')
->assertVisible('@email ~ .input-help.error')
->assertSeeIn('@email ~ .input-help.error', 'The email field must be a valid email.')
->type('@email', 'admin@example.com')
->assertMissing('@email ~ .input-help.error');
});
}
/**
* Test that entering the wrong password for an account returns an error.
*/
public function testInvalidPasswordShowsError()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->loginAs($this->user)
->visit(new AccountPage())
->type('@email', 'new.email@example.com')
->click('@submit')
->assertFocused('@password')
->type('@password', 'test1234')
->click('@submit')
->waitFor('@@error')
->assertSeeIn('@@error', trans('validation.internal.invalid_password'))
->assertValue('@email', 'new.email@example.com');
$this->assertDatabaseMissing('users', ['id' => $this->user->id, 'email' => 'new.email@example.com']);
});
}
}

View file

@ -1,55 +0,0 @@
<?php
namespace Pterodactyl\Tests\Browser\Processes\Dashboard;
use Pterodactyl\Tests\Browser\PterodactylBrowser;
use Pterodactyl\Tests\Browser\Pages\Dashboard\AccountPage;
class AccountPasswordProcessTest extends DashboardTestCase
{
/**
* Test that a user is able to change their password.
*/
public function testPasswordCanBeChanged()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->loginAs($this->user)
->visit(new AccountPage())
->type('@current_password', self::$userPassword)
->assertMissing('@new_password ~ .input-help.error')
->type('@new_password', 'test')
->assertSeeIn('@new_password ~ .input-help.error', 'The password field must be at least 8 characters.')
->type('@new_password', 'Test1234')
->assertMissing('@new_password ~ .input-help.error')
->assertMissing('@confirm_password ~ .input-help.error')
->type('@confirm_password', 'test')
->assertSeeIn('@confirm_password ~ .input-help.error', 'The password value is not valid.')
->type('@confirm_password', 'Test1234')
->assertMissing('@confirm_password ~ .input-help.error')
->click('@submit_password')
->waitFor('@@success')
->assertSeeIn('@@success', 'Your password has been updated.')
->assertInputValue('@current_password', '')
->assertInputValue('@new_password', '')
->assertInputValue('@confirm_password', '');
});
}
/**
* Test that invalid passwords result in the expected error message.
*/
public function testInvalidPassword()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->loginAs($this->user)
->visit(new AccountPage())
->type('@current_password', 'badpassword')
->type('@new_password', 'testtest')
->type('@confirm_password', 'testtest')
->click('@submit_password')
->waitFor('@@error')
->assertSeeIn('@@error', trans('validation.internal.invalid_password'))
->assertInputValue('@current_password', '');
});
}
}

View file

@ -1,23 +0,0 @@
<?php
namespace Pterodactyl\Tests\Browser\Processes\Dashboard;
use Pterodactyl\Tests\Browser\BrowserTestCase;
abstract class DashboardTestCase extends BrowserTestCase
{
/**
* @var \Pterodactyl\Models\User
*/
protected $user;
/**
* Setup tests and provide a default user to calling functions.
*/
protected function setUp(): void
{
parent::setUp();
$this->user = $this->user();
}
}

View file

@ -1,111 +0,0 @@
<?php
namespace Pterodactyl\Tests\Browser\Processes\Dashboard;
use PragmaRX\Google2FA\Google2FA;
use Facebook\WebDriver\WebDriverKeys;
use Illuminate\Support\Facades\Crypt;
use Pterodactyl\Tests\Browser\PterodactylBrowser;
use Pterodactyl\Tests\Browser\Pages\Dashboard\AccountPage;
class TwoFactorAuthenticationProcessTest extends DashboardTestCase
{
/**
* Test that the modal can be opened and closed.
*/
public function testModalOpenAndClose()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->loginAs($this->user)
->visit(new AccountPage())
->assertMissing('.modal-mask')
->click('@2fa_button')
->waitFor('@2fa_modal')
->pause(500)// seems to fix fragile test
->clickPosition(100, 100)
->waitUntilMissing('@2fa_modal')
->click('@2fa_button')
->waitFor('@2fa_modal')
->click('svg[role="button"][aria-label="Close modal"]')
->waitUntilMissing('@2fa_modal')
->click('@2fa_button')
->waitFor('@2fa_modal')
->keys('', [WebDriverKeys::ESCAPE])
->waitUntilMissing('@2fa_modal');
});
}
/**
* Test that a user that does not have two-factor enabled can enable it on their account.
*/
public function testTwoFactorCanBeEnabled()
{
$this->browse(function (PterodactylBrowser $browser) {
$browser->loginAs($this->user)
->visit(new AccountPage())
->click('@2fa_button')
->waitForText(trans('dashboard/account.two_factor.setup.title'))
->assertFocused('@2fa_token')
->waitFor('#grid-qr-code')
->assertSee(trans('dashboard/account.two_factor.setup.help'));
// Grab information from the database so we can ensure the correct things are showing up.
// Also because we need to generate a code to send through and activate it with.
$updated = $this->user->fresh();
$secret = Crypt::decrypt($updated->totp_secret);
$code = (new Google2FA())->getCurrentOtp($secret);
$browser->assertSeeIn('code', $secret)
->assertVisible('@2fa_enable[disabled="disabled"]')
->assertMissing('@2fa_token ~ .input-help.error')
->type('@2fa_token', '12')
->assertSeeIn('@2fa_token ~ .input-help.error', 'The token length must be 6.')
->type('@2fa_token', $code)
->assertMissing('@2fa_token ~ .input-help.error')
->click('@2fa_enable')
->waitUntilMissing('@2fa_modal')
->assertSeeIn('@@success', trans('dashboard/account.two_factor.enabled'));
$this->assertDatabaseHas('users', ['id' => $this->user->id, 'use_totp' => 1]);
});
}
/**
* Test that a user can disable two-factor authentication on thier account.
*/
public function testTwoFactorCanBeDisabled()
{
$secret = (new Google2FA())->generateSecretKey(16);
$this->user->update([
'use_totp' => true,
'totp_secret' => Crypt::encrypt($secret),
]);
$this->browse(function (PterodactylBrowser $browser) use ($secret) {
$browser->loginAs($this->user)
->visit(new AccountPage())
->click('@2fa_button')
->waitForText(trans('dashboard/account.two_factor.disable.title'))
->click('@2fa_cancel')
->waitUntilMissing('@2fa_modal')
->click('@2fa_button')
->waitForText(trans('dashboard/account.two_factor.disable.title'))
->assertVisible('@2fa_disable[disabled="disabled"]')
->assertVisible('@2fa_cancel')
->assertFocused('@2fa_token_disable')
->assertMissing('@2fa_token_disable ~ .input-help.error')
->type('@2fa_token_disable', '12')
->assertSeeIn('@2fa_token_disable ~ .input-help.error', 'The token length must be 6.');
$token = (new Google2FA())->getCurrentOtp($secret);
$browser->type('@2fa_token_disable', $token)
->assertMissing('@2fa_token_disable ~ .input-help.error')
->click('@2fa_disable')
->waitUntilMissing('@2fa_modal')
->assertSeeIn('@@success', trans('dashboard/account.two_factor.disabled'));
});
}
}

View file

@ -1,55 +0,0 @@
<?php
namespace Pterodactyl\Tests\Browser;
use Laravel\Dusk\Browser;
use Illuminate\Support\Str;
use PHPUnit\Framework\Assert as PHPUnit;
class PterodactylBrowser extends Browser
{
/**
* Move the mouse to a specific location and then perform a left click action.
*
* @return $this
*/
public function clickPosition(int $x, int $y)
{
$this->driver->getMouse()->mouseMove(null, $x, $y)->click();
return $this;
}
/**
* Perform a case insensitive search for a string in the body.
*
* @param string $text
*
* @return \Pterodactyl\Tests\Browser\PterodactylBrowser
*/
public function assertSee($text)
{
return $this->assertSeeIn('', $text);
}
/**
* Perform a case insensitive search for a string in a given selector.
*
* @param string $selector
* @param string $text
*
* @return \Pterodactyl\Tests\Browser\PterodactylBrowser
*/
public function assertSeeIn($selector, $text)
{
$fullSelector = $this->resolver->format($selector);
$element = $this->resolver->findOrFail($selector);
PHPUnit::assertTrue(
Str::contains(mb_strtolower($element->getText()), mb_strtolower($text)),
"Did not see expected text [{$text}] within element [{$fullSelector}] using case-insensitive search."
);
return $this;
}
}

View file

@ -1,2 +0,0 @@
*
!.gitignore

View file

@ -1,2 +0,0 @@
*
!.gitignore