This commit is contained in:
Mark Gregory
2026-06-16 21:19:22 +01:00
parent e96f1cc7bd
commit b3e4c4841e
6 changed files with 11 additions and 449 deletions
+1
View File
@@ -10,6 +10,7 @@
<testsuites>
<testsuite name="Browser Test Suite">
<directory suffix="Test.php">./tests/Browser</directory>
<directory suffix="Test.php">./Modules/Helpdesk/Tests/Browser</directory>
</testsuite>
</testsuites>
<php>
+10 -1
View File
@@ -7,10 +7,19 @@
<testsuites>
<testsuite name="Unit">
<directory>tests/Unit</directory>
<directory>Modules/Helpdesk/Tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory>tests/Feature</directory>
<directory>Modules/*/tests/Feature</directory>
<directory>Modules/Countries/Tests/Feature</directory>
<directory>Modules/Documentation/Tests/Feature</directory>
<directory>Modules/Helpdesk/Tests/Feature</directory>
<directory>Modules/InternalApi/tests/Feature</directory>
<directory>Modules/Platform/tests/Feature</directory>
<directory>Modules/Warehouse/tests/Feature</directory>
</testsuite>
</testsuites>
<source>
@@ -1,157 +0,0 @@
<?php
declare(strict_types=1);
namespace Tests\Browser\Concerns;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Schema;
use Laravel\Dusk\Browser;
trait InteractsWithWmsNavigation
{
protected function platformAdminUser(array $attributes = []): User
{
$companyId = null;
if (class_exists('App\\Models\\Company') && Schema::hasTable('companies')) {
/** @var class-string $companyClass */
$companyClass = 'App\\Models\\Company';
$companyAttributes = [
'name' => 'MPBA Limited',
];
$companyValues = [];
foreach ([
'slug' => 'mpba-limited',
'timezone' => 'Europe/London',
'billing_email' => 'platform-admin@mpba.co.uk',
'status' => 'active',
'is_system_company' => true,
] as $column => $value) {
if (Schema::hasColumn('companies', $column)) {
$companyValues[$column] = $value;
}
}
$company = $companyClass::query()->updateOrCreate($companyAttributes, $companyValues);
$companyId = $company->getKey();
}
$userAttributes = array_merge([
'name' => 'Mark Gregory',
'email' => 'mark.gregory@mpba.co.uk',
'password' => Hash::make('password'),
'email_verified_at' => now(),
], $attributes);
if ($companyId !== null && Schema::hasColumn('users', 'company_id')) {
$userAttributes['company_id'] = $companyId;
}
/** @var User $user */
$user = User::factory()->create($userAttributes);
foreach ([
'is_platform_admin' => true,
'is_mpba_platform_admin' => true,
'platform_admin' => true,
] as $column => $value) {
if (Schema::hasColumn('users', $column)) {
$user->forceFill([$column => $value]);
}
}
$user->save();
if (method_exists($user, 'assignRole')) {
try {
$user->assignRole('platform-admin');
} catch (\Throwable) {
// Some test databases do not seed Spatie roles for Dusk; the MPBA email/company is enough for this app helper.
}
}
return $user;
}
protected function resetNavigatorState(Browser $browser): Browser
{
$browser->script(<<<'JS'
localStorage.setItem('wms-sidebar-state', 'expanded');
localStorage.removeItem('wms-platform-menu-opened');
document.documentElement.dataset.wmsSidebar = 'expanded';
document.documentElement.dataset.wmsMobileSidebar = 'closed';
document.body.classList.remove('wms-mobile-nav-open');
JS);
return $browser->pause(150);
}
protected function openSidebarGroup(Browser $browser, string $group): Browser
{
$browser->script(<<<JS
const group = document.querySelector('[data-wms-menu-group="{$group}"]');
if (group) {
group.scrollIntoView({ block: 'center', inline: 'nearest' });
const toggle = group.querySelector('[data-wms-menu-toggle]');
if (toggle && group.dataset.wmsMenuOpen !== 'true') {
toggle.click();
}
}
JS);
return $browser->pause(150);
}
protected function assertSidebarGroupContains(Browser $browser, string $group, array $labels): Browser
{
$this->openSidebarGroup($browser, $group);
foreach ($labels as $label) {
$browser->assertSee($label);
}
return $browser;
}
protected function openMobileNavigation(Browser $browser): Browser
{
$browser->script(<<<'JS'
const button = document.querySelector('[data-wms-mobile-open]');
if (button) {
button.click();
}
JS);
return $browser->pause(250);
}
protected function closeMobileNavigation(Browser $browser): Browser
{
$browser->script(<<<'JS'
const button = document.querySelector('[data-wms-mobile-close]');
if (button) {
button.click();
}
JS);
return $browser->pause(200);
}
protected function clickSidebarHref(Browser $browser, string $href): Browser
{
$browser->script(<<<JS
const link = document.querySelector('.wms-sidebar a[href="{$href}"]');
if (link) {
link.scrollIntoView({ block: 'center', inline: 'nearest' });
link.click();
}
JS);
return $browser->pause(300);
}
}
@@ -1,133 +0,0 @@
<?php
declare(strict_types=1);
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\InteractsWithWmsNavigation;
use Tests\DuskTestCase;
final class DesktopNavigationBrowserTest extends DuskTestCase
{
use DatabaseMigrations;
use InteractsWithWmsNavigation;
public function test_desktop_sidebar_lists_every_navigator_option(): void
{
$admin = $this->platformAdminUser();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->resize(1440, 1000)
->visit('/admin')
->waitFor('.wms-sidebar', 10);
$this->resetNavigatorState($browser);
$this->assertSidebarGroupContains($browser, 'platform', [
'Platform',
]);
$this->assertSidebarGroupContains($browser, 'operations', [
'Analytics',
'Inventory',
'Replenishment',
'Shipping',
'Transportation',
'Carriers',
]);
$this->assertSidebarGroupContains($browser, 'integration-reporting', [
'M3 Integration',
'Sentinel',
'Documents',
'Reporting',
]);
$this->assertSidebarGroupContains($browser, 'administration', [
'Warehouses',
'Validation Rules',
'Prices',
'Configuration',
'Security',
'Audit',
]);
$this->assertSidebarGroupContains($browser, 'platform-administration', [
'Companies',
'Licences',
'Payments',
]);
});
}
public function test_desktop_sidebar_collapse_and_brand_expand_preserve_navigation(): void
{
$admin = $this->platformAdminUser();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->resize(1440, 1000)
->visit('/admin')
->waitFor('.wms-sidebar', 10);
$this->resetNavigatorState($browser);
$browser->script("document.querySelector('[data-wms-sidebar-toggle]')?.click();");
$browser->pause(200)
->assertPresent('.wms-sidebar');
$browser->script("document.querySelector('[data-wms-brand-toggle]')?.click();");
$browser->pause(200);
$this->assertSidebarGroupContains($browser, 'operations', [
'Analytics',
'Inventory',
]);
});
}
public function test_every_desktop_navigator_page_has_one_professional_header(): void
{
$admin = $this->platformAdminUser();
$paths = [
'/admin',
'/analytics',
'/inventory-management',
'/replenishment',
'/shipping',
'/transportation',
'/carrier-management',
'/m3-integration',
'/sentinel-integration',
'/document-archive',
'/reporting',
'/warehouses',
'/warehouse-rules',
'/platform/prices',
'/configuration',
'/security',
'/audit',
'/platform/companies',
'/platform/licenses',
'/platform/payments',
];
$this->browse(function (Browser $browser) use ($admin, $paths): void {
$browser->loginAs($admin)->resize(1440, 1000);
foreach ($paths as $path) {
$browser->visit($path)
->waitFor('.wms-page-hero', 10)
->assertPresent('.wms-page-hero');
$heroCount = $browser->script("return document.querySelectorAll('.wms-page-hero').length;")[0] ?? 0;
$this->assertSame(1, (int) $heroCount, "Expected one professional page hero on [{$path}].");
}
});
}
}
@@ -1,84 +0,0 @@
<?php
declare(strict_types=1);
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\InteractsWithWmsNavigation;
use Tests\DuskTestCase;
final class MobileNavigationBrowserTest extends DuskTestCase
{
use DatabaseMigrations;
use InteractsWithWmsNavigation;
public function test_mobile_hamburger_opens_and_closes_professional_drawer(): void
{
$admin = $this->platformAdminUser();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->resize(390, 844)
->visit('/admin')
->waitFor('[data-wms-mobile-open]', 10);
$this->openMobileNavigation($browser);
$browser->assertSee('Platform');
$this->assertSidebarGroupContains($browser, 'administration', [
'Prices',
]);
$this->closeMobileNavigation($browser);
$browser->assertPresent('[data-wms-mobile-open]');
});
}
public function test_mobile_drawer_navigates_to_major_menu_groups(): void
{
$admin = $this->platformAdminUser();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->resize(390, 844)
->visit('/admin')
->waitFor('[data-wms-mobile-open]', 10);
$this->openMobileNavigation($browser);
$this->assertSidebarGroupContains($browser, 'operations', ['Inventory']);
$this->clickSidebarHref($browser, '/inventory-management');
$browser->assertSee('Inventory');
$this->openMobileNavigation($browser);
$this->assertSidebarGroupContains($browser, 'administration', ['Warehouses']);
$this->clickSidebarHref($browser, '/warehouses');
$browser->assertSee('Warehouses');
});
}
public function test_mobile_tablet_and_desktop_breakpoints_keep_navigation_accessible(): void
{
$admin = $this->platformAdminUser();
$this->browse(function (Browser $browser) use ($admin): void {
foreach ([[390, 844], [834, 1112], [1440, 1000]] as [$width, $height]) {
$browser->loginAs($admin)
->resize($width, $height)
->visit('/admin')
->waitFor('.wms-app-shell', 10)
->assertPresent('.wms-app-shell');
if ($width < 1024) {
$browser->assertPresent('[data-wms-mobile-open]');
continue;
}
$browser->assertPresent('.wms-sidebar');
}
});
}
}
@@ -1,74 +0,0 @@
<?php
declare(strict_types=1);
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\InteractsWithWmsNavigation;
use Tests\DuskTestCase;
final class WmsResponsiveNavigationTest extends DuskTestCase
{
use DatabaseMigrations;
use InteractsWithWmsNavigation;
public function test_desktop_sidebar_navigation_remains_unchanged(): void
{
$admin = $this->platformAdminUser();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->resize(1440, 1000)
->visit('/admin')
->waitFor('.wms-sidebar', 10)
->assertSee('Platform');
$this->resetNavigatorState($browser);
$this->assertSidebarGroupContains($browser, 'operations', [
'Analytics',
'Inventory',
]);
$this->clickSidebarHref($browser, '/inventory-management');
$browser->assertSee('Inventory');
});
}
public function test_mobile_menu_opens_slide_out_navigation(): void
{
$admin = $this->platformAdminUser();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->resize(390, 844)
->visit('/admin')
->waitFor('[data-wms-mobile-open]', 10);
$this->openMobileNavigation($browser);
$browser->assertSee('Platform');
$this->assertSidebarGroupContains($browser, 'operations', ['Inventory']);
});
}
public function test_mobile_menu_overlay_closes_drawer(): void
{
$admin = $this->platformAdminUser();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->resize(390, 844)
->visit('/admin')
->waitFor('[data-wms-mobile-open]', 10);
$this->openMobileNavigation($browser);
$browser->assertSee('Platform');
$browser->script("document.querySelector('[data-wms-mobile-close]')?.click();");
$browser->pause(200)
->assertPresent('[data-wms-mobile-open]');
});
}
}