UPDATED TESTS

This commit is contained in:
Mark Gregory
2026-06-11 14:45:25 +01:00
parent 8b9de7426a
commit cad45a870d
13 changed files with 888 additions and 8 deletions
+14 -1
View File
@@ -12,11 +12,24 @@ return Application::configure(basePath: dirname(__DIR__))
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {
$middleware->trustProxies(
at: '*',
headers: Request::HEADER_X_FORWARDED_FOR
| Request::HEADER_X_FORWARDED_HOST
| Request::HEADER_X_FORWARDED_PORT
| Request::HEADER_X_FORWARDED_PROTO
);
$environment = $_ENV['APP_ENV']
?? $_SERVER['APP_ENV']
?? getenv('APP_ENV')
?: null;
if ($environment === 'testing') {
$middleware->validateCsrfTokens(except: ['*']);
}
+5 -2
View File
@@ -7,17 +7,20 @@
"dev": "vite"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^7.1.0",
"@laravel/passkeys": "^0.2.0",
"@tailwindcss/vite": "^4.1.11",
"concurrently": "^9.0.1",
"laravel-vite-plugin": "^3.1",
"tailwindcss": "^4.0.7",
"vite": "^8.0.0",
"@fortawesome/fontawesome-free": "^7.1.0"
"vite": "^8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "4.9.5",
"@tailwindcss/oxide-linux-x64-gnu": "^4.0.1",
"lightningcss-linux-x64-gnu": "^1.29.1"
},
"devDependencies": {
"chokidar": "^5.0.0"
}
}
+75
View File
@@ -0,0 +1,75 @@
<?php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\InteractsWithWmsData;
use Tests\DuskTestCase;
class AuthBrowserTest extends DuskTestCase
{
use DatabaseMigrations;
use InteractsWithWmsData;
public function test_login_page_renders_professional_auth_form(): void
{
$this->browse(function (Browser $browser): void {
$browser->visit('/login')
->assertSee('Log in')
->assertPresent('input[name="email"]')
->assertPresent('input[name="password"]')
->assertPresent('[data-test="login-button"]');
});
}
public function test_invalid_login_stays_on_login_page(): void
{
$this->platformAdminUser();
$this->browse(function (Browser $browser): void {
$browser->visit('/login')
->type('email', 'platform.admin@example.test')
->type('password', 'wrong-password')
->press('Log in')
->waitForLocation('/login')
->assertPathIs('/login');
});
}
public function test_platform_admin_can_login_and_logout(): void
{
$this->platformAdminUser();
$this->browse(function (Browser $browser): void {
$browser->visit('/login')
->type('email', 'platform.admin@example.test')
->type('password', $this->browserPassword)
->press('Log in')
->waitForLocation('/admin')
->assertPathIs('/admin')
->assertSee('Platform')
->click('.wms-user-card-button')
->waitFor('[data-test="logout-button"]')
->click('[data-test="logout-button"]')
->waitForLocation('/')
->assertPathIs('/');
});
}
public function test_tenant_user_login_routes_to_warehouse_dashboard(): void
{
$this->tenantUser();
$this->seedWarehouse();
$this->browse(function (Browser $browser): void {
$browser->visit('/login')
->type('email', 'tenant.user@example.test')
->type('password', $this->browserPassword)
->press('Log in')
->waitForLocation('/dashboard')
->assertPathIs('/dashboard')
->assertSee('Main Warehouse');
});
}
}
@@ -0,0 +1,46 @@
<?php
namespace Tests\Browser\Concerns;
use Laravel\Dusk\Browser;
trait InteractsWithWmsBrowser
{
protected function assertSingleProfessionalHeader(Browser $browser, string $title, ?string $description = null): void
{
$browser->assertSee($title)
->assertPresent('.wms-page-hero')
->assertScript('document.querySelectorAll(".wms-page-hero").length === 1');
if ($description !== null) {
$browser->assertSee($description);
}
}
protected function assertDesktopSidebarIsAvailable(Browser $browser): void
{
$browser->resize(1440, 1000)
->waitFor('.wms-sidebar', 5)
->assertVisible('.wms-sidebar')
->assertPresent('[data-wms-sidebar-toggle]')
->assertVisible('.wms-content');
}
protected function openMobileNavigation(Browser $browser): void
{
$browser->resize(390, 844)
->waitFor('.wms-mobile-header', 5)
->assertVisible('.wms-mobile-header')
->assertVisible('[data-wms-mobile-open]')
->click('[data-wms-mobile-open]')
->pause(250)
->assertScript('document.querySelector("[data-wms-mobile-shell]").classList.contains("is-mobile-open")');
}
protected function closeMobileNavigation(Browser $browser): void
{
$browser->click('[data-wms-mobile-close]')
->pause(250)
->assertScript('! document.querySelector("[data-wms-mobile-shell]").classList.contains("is-mobile-open")');
}
}
@@ -0,0 +1,158 @@
<?php
namespace Tests\Browser\Concerns;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Modules\Platform\app\Models\Company;
use Modules\Platform\app\Models\LicenseKey;
use Modules\Platform\app\Models\Payment;
use Modules\Platform\app\Models\PlatformPrice;
use Modules\Warehouse\app\Models\Warehouse;
use Modules\Warehouse\app\Models\WarehouseValidationRule;
trait InteractsWithWmsData
{
protected string $browserPassword = 'Password1!';
protected function platformAdminUser(array $overrides = []): User
{
$company = Company::query()->firstOrCreate(
['slug' => 'mpba-limited'],
[
'name' => 'MPBA Limited',
'status' => 'active',
'timezone' => 'Europe/London',
'is_system_company' => true,
'billing_email' => 'mark.gregory@mpba.co.uk',
],
);
return User::query()->updateOrCreate(
['email' => $overrides['email'] ?? 'platform.admin@example.test'],
[
'company_id' => $company->id,
'name' => $overrides['name'] ?? 'Platform Admin',
'password' => Hash::make($this->browserPassword),
'email_verified_at' => now(),
'is_platform_admin' => true,
'is_company_admin' => true,
'status' => 'active',
...$overrides,
],
);
}
protected function tenantUser(array $overrides = []): User
{
$company = $this->tenantCompany();
return User::query()->updateOrCreate(
['email' => $overrides['email'] ?? 'tenant.user@example.test'],
[
'company_id' => $company->id,
'name' => $overrides['name'] ?? 'Tenant User',
'password' => Hash::make($this->browserPassword),
'email_verified_at' => now(),
'is_platform_admin' => false,
'is_company_admin' => true,
'status' => 'active',
...$overrides,
],
);
}
protected function tenantCompany(array $overrides = []): Company
{
$company = Company::query()->updateOrCreate(
['slug' => $overrides['slug'] ?? 'test-company'],
[
'name' => $overrides['name'] ?? 'Test Company',
'status' => $overrides['status'] ?? 'active',
'timezone' => 'Europe/London',
'is_system_company' => false,
'billing_email' => $overrides['billing_email'] ?? 'billing@test-company.example',
...$overrides,
],
);
if (! $company->hasActiveLicense()) {
LicenseKey::issueFor($company, 'Browser Test Licence', 'enterprise', 250);
}
return $company;
}
protected function seedPlatformPrices(): void
{
foreach ([
['basic', 'Basic', 'Starter WMS access', 'Core warehouse management for small teams.', 4900, 49000, 10, false, true, ['2 warehouses', '10 users', 'Standard support']],
['advanced', 'Advanced', 'Growing WMS operations', 'More users, warehouses and automation controls.', 14900, 149000, 20, true, true, ['5 warehouses', '100 users', 'Advanced support']],
['pro', 'Pro', 'Professional WMS command centre', 'Full operational visibility for larger teams.', 29900, 299000, 30, false, true, ['15 warehouses', 'Unlimited dashboards', 'Priority support']],
] as [$code, $name, $strapline, $description, $monthly, $annual, $sortOrder, $featured, $active, $features]) {
PlatformPrice::query()->updateOrCreate(
['code' => $code],
[
'name' => $name,
'strapline' => $strapline,
'description' => $description,
'monthly_amount' => $monthly,
'annual_amount' => $annual,
'currency' => 'gbp',
'badge_label' => $featured ? 'Popular' : null,
'features' => $features,
'sort_order' => $sortOrder,
'is_featured' => $featured,
'is_active' => $active,
],
);
}
}
protected function seedWarehouse(?Company $company = null): Warehouse
{
$company ??= $this->tenantCompany();
$warehouse = Warehouse::query()->updateOrCreate(
['company_id' => $company->id, 'code' => 'MAIN'],
[
'name' => 'Main Warehouse',
'address' => 'Main Road, Nottingham',
'status' => 'active',
'timezone' => 'Europe/London',
],
);
WarehouseValidationRule::query()->updateOrCreate(
['warehouse_id' => $warehouse->id, 'rule_key' => 'batch-required'],
[
'name' => 'Require batch number',
'severity' => 'blocker',
'is_active' => true,
'configuration' => ['field' => 'batch_no'],
],
);
return $warehouse;
}
protected function seedPlatformDashboardData(): void
{
$company = $this->tenantCompany(['name' => 'Customer One', 'slug' => 'customer-one']);
$this->seedWarehouse($company);
$this->seedPlatformPrices();
Payment::query()->updateOrCreate(
['stripe_payment_intent_id' => 'pi_browser_paid'],
[
'company_id' => $company->id,
'amount' => 12345,
'currency' => 'gbp',
'status' => 'paid',
'description' => 'Browser test payment',
'paid_at' => now(),
'metadata' => ['source' => 'dusk'],
],
);
}
}
@@ -0,0 +1,109 @@
<?php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\InteractsWithWmsBrowser;
use Tests\Browser\Concerns\InteractsWithWmsData;
use Tests\DuskTestCase;
class DesktopNavigationBrowserTest extends DuskTestCase
{
use DatabaseMigrations;
use InteractsWithWmsBrowser;
use InteractsWithWmsData;
public function test_desktop_sidebar_lists_every_navigator_option(): void
{
$admin = $this->platformAdminUser();
$this->seedPlatformDashboardData();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->visit('/admin');
$this->assertDesktopSidebarIsAvailable($browser);
foreach ([
'Platform', 'Analytics', 'Inventory', 'Replenishment', 'Shipping', 'Transportation', 'Carriers',
'M3 Integration', 'Sentinel', 'Documents', 'Reporting', 'Warehouses', 'Validation Rules',
'Pricing', 'Configuration', 'Security', 'Audit', 'Companies', 'Licences', 'Payments', 'Prices',
] as $label) {
$browser->assertSee($label);
}
});
}
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')
->click('[data-wms-sidebar-toggle]')
->pause(250)
->assertScript('document.querySelector("[data-wms-shell]").classList.contains("is-sidebar-collapsed")')
->assertPresent('[data-wms-brand-toggle]')
->click('[data-wms-brand-toggle]')
->pause(250)
->assertScript('! document.querySelector("[data-wms-shell]").classList.contains("is-sidebar-collapsed")')
->clickLink('Analytics')
->waitForLocation('/analytics')
->assertSee('Analytics');
});
}
/**
* @dataProvider navigatorRoutes
*/
public function test_every_desktop_navigator_page_has_one_professional_header(string $path, string $title): void
{
$admin = $this->platformAdminUser();
$this->seedPlatformDashboardData();
$this->browse(function (Browser $browser) use ($admin, $path, $title): void {
$browser->loginAs($admin)
->resize(1440, 1000)
->visit($path)
->waitFor('.wms-page-hero', 5);
$this->assertSingleProfessionalHeader($browser, $title);
$browser->assertVisible('.wms-sidebar');
});
}
/**
* @return array<string, array{0: string, 1: string}>
*/
public static function navigatorRoutes(): array
{
return [
'platform' => ['/admin', 'Platform'],
'platform pricing' => ['/platform/pricing', 'Pricing'],
'companies' => ['/admin/companies', 'Companies'],
'licences' => ['/admin/licenses', 'Licence Keys'],
'payments' => ['/admin/payments', 'Payments'],
'price crud' => ['/admin/prices', 'Platform Prices'],
'warehouse dashboard' => ['/dashboard', 'Warehouse'],
'warehouses' => ['/warehouses', 'Warehouses'],
'validation rules' => ['/warehouse-rules', 'Validation Rules'],
'analytics' => ['/analytics', 'Analytics'],
'inventory' => ['/inventory-management', 'Inventory'],
'replenishment' => ['/replenishment', 'Replenishment'],
'shipping' => ['/shipping', 'Shipping'],
'transportation' => ['/transportation', 'Transportation'],
'carriers' => ['/carrier-management', 'Carriers'],
'm3' => ['/m3-integration', 'M3 Integration'],
'sentinel' => ['/sentinel-integration', 'Sentinel'],
'documents' => ['/document-archive', 'Documents'],
'reporting' => ['/reporting', 'Reporting'],
'configuration' => ['/configuration', 'Configuration'],
'security' => ['/security', 'Security'],
'audit' => ['/audit', 'Audit'],
];
}
}
+19 -5
View File
@@ -4,18 +4,32 @@ namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\InteractsWithWmsData;
use Tests\DuskTestCase;
class ExampleTest extends DuskTestCase
{
/**
* A basic browser test example.
*/
public function test_basic_example(): void
use DatabaseMigrations;
use InteractsWithWmsData;
public function test_application_homepage_is_reachable_in_browser(): void
{
$this->browse(function (Browser $browser) {
$this->browse(function (Browser $browser): void {
$browser->visit('/')
->assertSee('Laravel');
});
}
public function test_authenticated_application_shell_is_reachable_in_browser(): void
{
$admin = $this->platformAdminUser();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->visit('/admin')
->waitFor('.wms-app-shell', 5)
->assertPresent('.wms-sidebar')
->assertPresent('.wms-content');
});
}
}
@@ -0,0 +1,81 @@
<?php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\InteractsWithWmsBrowser;
use Tests\Browser\Concerns\InteractsWithWmsData;
use Tests\DuskTestCase;
class MobileNavigationBrowserTest extends DuskTestCase
{
use DatabaseMigrations;
use InteractsWithWmsBrowser;
use InteractsWithWmsData;
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)
->visit('/admin');
$this->openMobileNavigation($browser);
$browser->assertVisible('.wms-sidebar')
->assertSee('Platform')
->assertSee('Administration')
->assertSee('Prices');
$this->closeMobileNavigation($browser);
});
}
public function test_mobile_drawer_navigates_to_every_major_menu_group(): void
{
$admin = $this->platformAdminUser();
$this->seedPlatformDashboardData();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->visit('/admin');
foreach ([
'Analytics' => '/analytics',
'Inventory' => '/inventory-management',
'Documents' => '/document-archive',
'Warehouses' => '/warehouses',
'Prices' => '/admin/prices',
] as $label => $path) {
$this->openMobileNavigation($browser);
$browser->clickLink($label)
->waitForLocation($path)
->waitFor('.wms-page-hero', 5)
->assertPathIs($path)
->assertSee($label === 'Prices' ? 'Platform Prices' : $label)
->assertScript('! document.querySelector("[data-wms-mobile-shell]").classList.contains("is-mobile-open")');
}
});
}
public function test_mobile_tablet_and_desktop_breakpoints_keep_navigation_accessible(): void
{
$admin = $this->platformAdminUser();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->visit('/admin')
->resize(390, 844)
->waitFor('.wms-mobile-header', 5)
->assertVisible('[data-wms-mobile-open]')
->resize(820, 1180)
->pause(250)
->assertVisible('[data-wms-mobile-open]')
->resize(1440, 1000)
->pause(250)
->assertVisible('.wms-sidebar')
->assertPresent('[data-wms-sidebar-toggle]');
});
}
}
@@ -0,0 +1,101 @@
<?php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\InteractsWithWmsBrowser;
use Tests\Browser\Concerns\InteractsWithWmsData;
use Tests\DuskTestCase;
class PlatformAdministrationBrowserTest extends DuskTestCase
{
use DatabaseMigrations;
use InteractsWithWmsBrowser;
use InteractsWithWmsData;
public function test_platform_dashboard_displays_counts_pricing_cards_and_recent_companies(): void
{
$admin = $this->platformAdminUser();
$this->seedPlatformDashboardData();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->visit('/admin')
->waitFor('.wms-page-hero', 5);
$this->assertSingleProfessionalHeader($browser, 'Platform');
$browser->assertSee('Basic')
->assertSee('Advanced')
->assertSee('Pro')
->assertSee('Customer One')
->assertSee('Prices');
});
}
public function test_company_administration_can_create_company_and_show_validation_errors(): void
{
$admin = $this->platformAdminUser();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->visit('/admin/companies')
->waitFor('.wms-page-hero')
->press('Create')
->waitForText('The name field is required', 5)
->type('name', 'Abbott Logistics Limited')
->type('billing_email', 'billing@abbott.example')
->select('status', 'active')
->press('Create')
->waitForText('Abbott Logistics Limited', 5)
->assertSee('Company created.')
->assertSee('Abbott Logistics Limited');
});
}
public function test_license_administration_can_issue_license(): void
{
$admin = $this->platformAdminUser();
$this->tenantCompany(['name' => 'Licence Customer', 'slug' => 'licence-customer']);
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->visit('/admin/licenses')
->waitFor('.wms-page-hero')
->type('label', 'Enterprise Licence')
->select('plan', 'enterprise')
->type('max_users', '500')
->press('Issue')
->waitForText('Licence key issued', 5)
->assertSee('Enterprise Licence')
->assertSee('enterprise');
});
}
public function test_payment_administration_can_record_paid_pending_and_validation_paths(): void
{
$admin = $this->platformAdminUser();
$this->tenantCompany(['name' => 'Payment Customer', 'slug' => 'payment-customer']);
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->visit('/admin/payments')
->waitFor('.wms-page-hero')
->type('amount', '12345')
->type('currency', 'gbp')
->select('status', 'paid')
->type('description', 'Manual bank transfer')
->press('Add')
->waitForText('Payment record created.', 5)
->assertSee('Manual bank transfer')
->assertSee('GBP 123.45')
->select('status', 'pending')
->type('amount', '5000')
->type('description', 'Awaiting payment')
->press('Add')
->waitForText('Awaiting payment', 5)
->assertSee('pending');
});
}
}
@@ -0,0 +1,96 @@
<?php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Modules\Platform\app\Models\PlatformPrice;
use Tests\Browser\Concerns\InteractsWithWmsBrowser;
use Tests\Browser\Concerns\InteractsWithWmsData;
use Tests\DuskTestCase;
class PlatformPricingBrowserTest extends DuskTestCase
{
use DatabaseMigrations;
use InteractsWithWmsBrowser;
use InteractsWithWmsData;
public function test_platform_pricing_page_shows_customer_card_grid_only_for_active_prices(): void
{
$user = $this->tenantUser();
$this->seedPlatformPrices();
PlatformPrice::query()->updateOrCreate(
['code' => 'hidden'],
[
'name' => 'Hidden',
'monthly_amount' => 1,
'currency' => 'gbp',
'features' => [],
'sort_order' => 99,
'is_featured' => false,
'is_active' => false,
],
);
$this->browse(function (Browser $browser) use ($user): void {
$browser->loginAs($user)
->visit('/platform/pricing')
->waitFor('.wms-page-hero', 5);
$this->assertSingleProfessionalHeader($browser, 'Pricing');
$browser->assertSee('Basic')
->assertSee('Advanced')
->assertSee('Pro')
->assertSee('£49.00')
->assertDontSee('Hidden');
});
}
public function test_admin_price_crud_create_edit_delete_and_validation_paths(): void
{
$admin = $this->platformAdminUser();
$this->seedPlatformPrices();
$this->browse(function (Browser $browser) use ($admin): void {
$browser->loginAs($admin)
->visit('/admin/prices')
->waitFor('.wms-page-hero')
->assertSee('Basic')
->clickLink('Create Price')
->waitForLocation('/admin/prices/create')
->waitFor('.wms-page-hero')
->press('Save Price')
->waitForText('The name field is required', 5)
->type('name', 'Ultimate Plan')
->type('code', 'ultimate-plan')
->type('strapline', 'Unlimited WMS operations')
->type('badge_label', 'Enterprise')
->type('monthly_amount', '499.00')
->type('annual_amount', '4990.00')
->type('currency', 'gbp')
->type('sort_order', '40')
->type('description', 'Unlimited warehouses and users for enterprise operators.')
->type('features', "Unlimited warehouses\nUnlimited users\nPriority support")
->check('is_featured')
->check('is_active')
->press('Save Price')
->waitForLocation('/admin/prices')
->assertSee('Price created.')
->assertSee('Ultimate Plan')
->clickLink('Edit')
->waitFor('.wms-page-hero')
->type('name', 'Ultimate Plus')
->type('monthly_amount', '599.00')
->press('Update Price')
->waitForLocation('/admin/prices')
->assertSee('Price updated.')
->assertSee('Ultimate Plus')
->press('Delete')
->acceptDialog()
->waitForText('Price deleted.', 5)
->assertDontSee('Ultimate Plus');
});
}
}
+35
View File
@@ -0,0 +1,35 @@
# WMS Dusk coverage pack
This pack adds browser coverage for the current WMS UI baseline:
- Authentication browser flows.
- Desktop sidebar navigation and collapse / expand behaviour.
- Mobile hamburger menu and slide-out drawer behaviour.
- Single professional page hero/header on navigator pages.
- Platform dashboard and pricing card display.
- Platform pricing customer grid.
- Administration pricing CRUD.
- Company, licence and payment administration forms.
- Warehouse dashboard, warehouse form and validation rule form.
- Mobile, tablet and desktop responsive rendering checks.
Run with:
```bash
php artisan dusk
```
Recommended local setup before running Dusk:
```bash
php artisan optimize:clear
php artisan migrate
php artisan dusk:chrome-driver --detect
```
If the app uses database sessions, make sure the sessions table exists:
```bash
php artisan session:table
php artisan migrate
```
@@ -0,0 +1,62 @@
<?php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\InteractsWithWmsBrowser;
use Tests\Browser\Concerns\InteractsWithWmsData;
use Tests\DuskTestCase;
class ResponsiveBaselineBrowserTest extends DuskTestCase
{
use DatabaseMigrations;
use InteractsWithWmsBrowser;
use InteractsWithWmsData;
/**
* @dataProvider responsivePages
*/
public function test_core_pages_render_on_mobile_tablet_and_desktop(string $path, string $title): void
{
$admin = $this->platformAdminUser();
$this->seedPlatformDashboardData();
$this->browse(function (Browser $browser) use ($admin, $path, $title): void {
$browser->loginAs($admin);
foreach ([[390, 844], [820, 1180], [1440, 1000]] as [$width, $height]) {
$browser->resize($width, $height)
->visit($path)
->waitFor('.wms-page-hero', 5);
$this->assertSingleProfessionalHeader($browser, $title);
if ($width < 1024) {
$browser->assertVisible('[data-wms-mobile-open]');
} else {
$browser->assertVisible('.wms-sidebar');
}
}
});
}
/**
* @return array<string, array{0: string, 1: string}>
*/
public static function responsivePages(): array
{
return [
'platform dashboard' => ['/admin', 'Platform'],
'platform pricing' => ['/platform/pricing', 'Pricing'],
'admin prices' => ['/admin/prices', 'Platform Prices'],
'warehouse dashboard' => ['/dashboard', 'Warehouse'],
'warehouses' => ['/warehouses', 'Warehouses'],
'validation rules' => ['/warehouse-rules', 'Validation Rules'],
'analytics' => ['/analytics', 'Analytics'],
'inventory' => ['/inventory-management', 'Inventory'],
'documents' => ['/document-archive', 'Documents'],
'configuration' => ['/configuration', 'Configuration'],
];
}
}
+87
View File
@@ -0,0 +1,87 @@
<?php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Concerns\InteractsWithWmsBrowser;
use Tests\Browser\Concerns\InteractsWithWmsData;
use Tests\DuskTestCase;
class WarehouseBrowserTest extends DuskTestCase
{
use DatabaseMigrations;
use InteractsWithWmsBrowser;
use InteractsWithWmsData;
public function test_tenant_warehouse_dashboard_and_administration_pages(): void
{
$user = $this->tenantUser();
$this->seedWarehouse();
$this->browse(function (Browser $browser) use ($user): void {
$browser->loginAs($user)
->visit('/dashboard')
->waitFor('.wms-page-hero')
->assertSee('Main Warehouse')
->assertSee('Require batch number')
->visit('/warehouses')
->waitFor('.wms-page-hero');
$this->assertSingleProfessionalHeader($browser, 'Warehouses');
$browser->assertSee('Main Warehouse')
->visit('/warehouse-rules')
->waitFor('.wms-page-hero');
$this->assertSingleProfessionalHeader($browser, 'Validation Rules');
$browser->assertSee('Require batch number')
->assertSee('batch-required');
});
}
public function test_warehouse_crud_forms_cover_create_and_validation_paths(): void
{
$user = $this->tenantUser();
$this->browse(function (Browser $browser) use ($user): void {
$browser->loginAs($user)
->visit('/warehouses')
->waitFor('.wms-page-hero')
->press('Create')
->waitForText('The code field is required', 5)
->type('code', 'EAST')
->type('name', 'East Midlands DC')
->type('address', 'Main Road, Nottingham')
->press('Create')
->waitForText('Warehouse created.', 5)
->assertSee('East Midlands DC');
});
}
public function test_validation_rule_form_covers_create_and_validation_paths(): void
{
$user = $this->tenantUser();
$this->seedWarehouse();
$this->browse(function (Browser $browser) use ($user): void {
$browser->loginAs($user)
->visit('/warehouse-rules')
->waitFor('.wms-page-hero')
->type('name', '')
->type('rule_key', '')
->type('configuration', '{bad json')
->press('Add rule')
->waitForText('The name field is required', 5)
->type('name', 'Require serial number')
->type('rule_key', 'serial-required')
->select('severity', 'error')
->type('configuration', '{"field":"serial_no"}')
->press('Add rule')
->waitForText('Validation rule created.', 5)
->assertSee('Require serial number')
->assertSee('serial-required');
});
}
}