diff --git a/.env.dusk.local.example b/.env.dusk.local.example new file mode 100644 index 0000000..2e5e64c --- /dev/null +++ b/.env.dusk.local.example @@ -0,0 +1,12 @@ +APP_NAME=ComboboxTest +APP_ENV=testing +APP_KEY=base64:7hJrI1l3H5UBVvEF3dUxHJb2C0dXoP2xC1qiJxz2A/w= +APP_DEBUG=true +APP_URL=http://localhost:8000 + +DB_CONNECTION=sqlite +DB_DATABASE=:memory: + +CACHE_DRIVER=array +QUEUE_CONNECTION=sync +SESSION_DRIVER=array diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 780dad5..dab27ac 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -45,3 +45,63 @@ jobs: - name: Execute tests run: vendor/bin/pest --ci + + browser-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.4 + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, fileinfo + + - name: Install dependencies + run: composer install --no-ansi --no-interaction --optimize-autoloader --prefer-dist + + - name: Setup Configuration + run: | + cp testbench.yaml.example testbench.yaml + cp .env.dusk.local.example .env.dusk.local + + - name: Upgrade Chrome Driver + run: php vendor/bin/dusk-updater detect --auto-update + + - name: Start Chrome Driver + run: ./vendor/laravel/dusk/bin/chromedriver-linux --port=9515 & + + - name: Setup and Migrate Database + run: | + php vendor/bin/testbench package:test-skeleton + php vendor/bin/testbench migrate:fresh + + - name: Run Dusk server + run: php vendor/bin/testbench serve & + env: + APP_URL: http://127.0.0.1:8000 + + - name: Wait for server + run: | + timeout 60 bash -c 'until curl -s http://127.0.0.1:8000 > /dev/null; do sleep 1; done' + + - name: Run Browser Tests + run: php vendor/bin/pest tests/Browser --colors=always + env: + APP_URL: http://127.0.0.1:8000 + DUSK_DRIVER_URL: http://localhost:9515 + + - name: Upload Screenshots + if: failure() + uses: actions/upload-artifact@v4 + with: + name: browser-test-screenshots + path: tests/Browser/screenshots + + - name: Upload Console Logs + if: failure() + uses: actions/upload-artifact@v4 + with: + name: browser-test-console-logs + path: tests/Browser/console diff --git a/.gitignore b/.gitignore index a99f6db..7a53285 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ phpstan.neon testbench.yaml vendor .pnpm-store +tests/Browser/screenshots +tests/Browser/console +.env.dusk.local diff --git a/BROWSER_TESTING.md b/BROWSER_TESTING.md new file mode 100644 index 0000000..81c086a --- /dev/null +++ b/BROWSER_TESTING.md @@ -0,0 +1,148 @@ +# Browser Testing + +This package includes browser tests using Laravel Dusk to test the Combobox component in a real browser environment. + +## Requirements + +- PHP 8.2+ +- Chrome/Chromium browser +- ChromeDriver (automatically managed by Dusk) + +## Running Browser Tests Locally + +### 1. Install Dependencies + +```bash +composer install +``` + +### 2. Setup Configuration + +Copy the example testbench configuration: + +```bash +cp testbench.yaml.example testbench.yaml +cp .env.dusk.local.example .env.dusk.local +``` + +### 3. Install/Update ChromeDriver + +```bash +php vendor/bin/dusk-updater detect --auto-update +``` + +### 3. Setup Database + +```bash +php vendor/bin/testbench migrate:fresh +``` + +### 4. Start the Test Server + +In one terminal, start the Testbench server: + +```bash +php vendor/bin/testbench serve +``` + +The server will start at `http://127.0.0.1:8000` + +### 5. Run Browser Tests + +In another terminal, run the browser tests: + +```bash +php vendor/bin/pest tests/Browser +``` + +## Screenshots + +Browser tests automatically capture screenshots during key interactions: + +- `before-combobox-interaction.png` - Form state before interacting with combobox +- `combobox-dropdown-open.png` - Combobox dropdown opened with options +- `combobox-option-selected.png` - After selecting an option +- `combobox-search-visible.png` - Search input visible +- `combobox-search-typed.png` - After typing in search +- `user-created.png` - Final state after creating user + +Screenshots are saved to `tests/Browser/screenshots/` + +## GitHub Actions + +Browser tests run automatically on every push and pull request. Screenshots from failed tests are uploaded as artifacts. + +To view screenshots from CI: +1. Go to the Actions tab +2. Select the workflow run +3. Download the `browser-test-screenshots` artifact + +## Test Coverage + +The browser tests cover: + +1. **Login Flow** - User authentication to admin panel +2. **Resource Access** - Accessing the User resource +3. **Combobox Interaction** - Creating a user with the combobox field +4. **Search Functionality** - Testing the combobox search feature + +## Debugging + +### View Browser in Non-Headless Mode + +To see the browser during test execution, set the `DUSK_HEADLESS_DISABLED` environment variable: + +```bash +DUSK_HEADLESS_DISABLED=1 php vendor/bin/pest tests/Browser +``` + +### Check Console Logs + +Console logs from failed tests are saved to `tests/Browser/console/` + +### Manual Testing + +You can manually test the admin panel by: + +1. Starting the server: `php vendor/bin/testbench serve` +2. Creating a test user in tinker: + ```bash + php vendor/bin/testbench tinker + ``` + ```php + User::create([ + 'name' => 'Test User', + 'email' => 'test@example.com', + 'password' => bcrypt('password'), + 'role' => 'admin' + ]); + ``` +3. Visit `http://127.0.0.1:8000/admin` and login + +## Troubleshooting + +### ChromeDriver Issues + +If you encounter ChromeDriver errors: + +```bash +# Update ChromeDriver +php vendor/bin/dusk-updater detect --auto-update + +# Or manually specify Chrome version +php vendor/bin/dusk-updater update --version=120 +``` + +### Port Already in Use + +If port 8000 is already in use, specify a different port: + +```bash +php vendor/bin/testbench serve --port=8080 +``` + +Then update the `APP_URL` in `.env.dusk.local`: + +``` +APP_URL=http://127.0.0.1:8080 +``` diff --git a/IMPLEMENTATION_SUMMARY.md b/IMPLEMENTATION_SUMMARY.md new file mode 100644 index 0000000..7b05cef --- /dev/null +++ b/IMPLEMENTATION_SUMMARY.md @@ -0,0 +1,178 @@ +# Browser Testing Implementation Summary + +This document summarizes the implementation of browser testing for the Filament Combobox package. + +## What Was Implemented + +### 1. FilamentPHP Admin Panel Setup in Testbench + +**New Files:** +- `workbench/app/Providers/Filament/AdminPanelProvider.php` - Filament admin panel configuration +- `workbench/app/Filament/Resources/UserResource.php` - User resource with Combobox field +- `workbench/app/Filament/Resources/UserResource/Pages/` - CRUD pages for User resource +- `workbench/resources/views/welcome.blade.php` - Welcome page with admin panel link + +**Modified Files:** +- `workbench/app/Providers/WorkbenchServiceProvider.php` - Registers AdminPanelProvider +- `workbench/app/Models/User.php` - Implements FilamentUser interface +- `workbench/database/factories/UserFactory.php` - Added role field +- `workbench/database/seeders/DatabaseSeeder.php` - Seeds admin user + +### 2. Database Migrations + +**New Files:** +- `workbench/database/migrations/0001_01_01_000010_add_role_to_users_table.php` - Adds role column to users table + +**Notes:** +- Uses testbench's built-in users table migration as base +- Adds only the `role` column needed for testing the combobox field + +### 3. Laravel Dusk Browser Testing + +**New Files:** +- `tests/DuskTestCase.php` - Base test case for browser tests +- `tests/CreatesApplication.php` - Trait for creating test application +- `tests/Browser/ComboboxTest.php` - Comprehensive browser tests for combobox component + +**Test Coverage:** +1. User login to admin panel +2. Accessing user resource +3. Creating user with combobox field +4. Combobox search functionality + +**Screenshots Captured:** +- before-combobox-interaction.png +- combobox-dropdown-open.png +- combobox-option-selected.png +- combobox-search-visible.png +- combobox-search-typed.png +- user-created.png + +**Modified Files:** +- `tests/Pest.php` - Configured to use DuskTestCase for Browser directory + +### 4. Configuration Files + +**New Files:** +- `testbench.yaml.example` - Example testbench configuration +- `.env.dusk.local.example` - Example Dusk environment configuration + +**Modified Files:** +- `.gitignore` - Added browser test artifacts (screenshots, console logs, .env.dusk.local) + +### 5. GitHub Actions Workflow + +**Modified Files:** +- `.github/workflows/run-tests.yml` - Added browser-tests job + +**New Job Features:** +- Installs and configures ChromeDriver +- Runs testbench server +- Executes browser tests +- Uploads screenshots and console logs as artifacts on failure + +### 6. Dependencies + +**Added to composer.json:** +- `filament/filament: ^4.0` (dev) - Full Filament panel package +- `laravel/dusk: ^8.3` (dev) - Browser testing framework + +### 7. Documentation + +**New Files:** +- `BROWSER_TESTING.md` - Comprehensive guide for running browser tests + +**Modified Files:** +- `README.md` - Added browser testing section with link to detailed guide + +## How to Use + +### Local Development + +1. Install dependencies: + ```bash + composer install + ``` + +2. Setup configuration: + ```bash + cp testbench.yaml.example testbench.yaml + cp .env.dusk.local.example .env.dusk.local + ``` + +3. Install ChromeDriver: + ```bash + php vendor/bin/dusk-updater detect --auto-update + ``` + +4. Run migrations: + ```bash + php vendor/bin/testbench migrate:fresh + ``` + +5. Start server (in one terminal): + ```bash + php vendor/bin/testbench serve + ``` + +6. Run browser tests (in another terminal): + ```bash + php vendor/bin/pest tests/Browser + ``` + +### GitHub Actions + +Browser tests run automatically on every push and pull request. Screenshots from failed tests are available as downloadable artifacts. + +## Key Design Decisions + +1. **Separate DuskTestCase**: Created a separate test case for browser tests to avoid conflicts with unit tests. + +2. **CreatesApplication Trait**: Isolated application creation logic to be reusable and testable. + +3. **Example Configuration Files**: Used `.example` suffix for configuration files to allow customization while providing working defaults. + +4. **Screenshot on Failure**: GitHub Actions only uploads screenshots when tests fail to save storage. + +5. **Headless Chrome**: Browser tests run in headless mode in CI for better performance. + +6. **In-Memory SQLite**: Uses in-memory database for fast test execution. + +## Testing the Admin Panel Manually + +1. Start the server: + ```bash + php vendor/bin/testbench serve + ``` + +2. Create a test user: + ```bash + php vendor/bin/testbench tinker + ``` + ```php + User::create([ + 'name' => 'Admin User', + 'email' => 'admin@example.com', + 'password' => bcrypt('password'), + 'role' => 'admin' + ]); + ``` + +3. Visit http://127.0.0.1:8000/admin and login with: + - Email: admin@example.com + - Password: password + +4. Navigate to Users resource to see the Combobox field in action. + +## Files Modified/Created Summary + +- **Total Files Modified/Created**: 22 +- **New Test Files**: 3 +- **New Workbench Files**: 9 +- **New Configuration Files**: 2 +- **New Documentation Files**: 2 +- **Modified Existing Files**: 6 + +## Next Steps + +The implementation is complete and ready for use. The browser tests will run automatically in CI/CD and can be run locally for development and debugging. diff --git a/README.md b/README.md index f7ab515..b0021fb 100644 --- a/README.md +++ b/README.md @@ -93,10 +93,26 @@ Combobox::make('product') ## Testing +### Unit Tests + ```bash composer test ``` +### Browser Tests + +The package includes comprehensive browser tests using Laravel Dusk to test the Combobox component in a real browser environment. + +```bash +# Run all tests including browser tests +php vendor/bin/pest + +# Run only browser tests +php vendor/bin/pest tests/Browser +``` + +For detailed information about browser testing, see [BROWSER_TESTING.md](BROWSER_TESTING.md). + ## Changelog Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. diff --git a/composer.json b/composer.json index b7598c3..1550851 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,8 @@ "spatie/laravel-package-tools": "^1.15.0" }, "require-dev": { + "filament/filament": "^4.0", + "laravel/dusk": "^8.3", "laravel/pint": "^1.25", "nunomaduro/collision": "^8.8.2", "orchestra/testbench": "^9.0", diff --git a/testbench.yaml.example b/testbench.yaml.example new file mode 100644 index 0000000..0b634f6 --- /dev/null +++ b/testbench.yaml.example @@ -0,0 +1,18 @@ +providers: + - Workbench\App\Providers\WorkbenchServiceProvider + +migrations: + - workbench/database/migrations + +workbench: + start: '/' + user: admin@example.com + guard: web + install: true + welcome: false + health: false + discovers: + web: true + api: true + commands: true + views: true diff --git a/tests/Browser/ComboboxTest.php b/tests/Browser/ComboboxTest.php new file mode 100644 index 0000000..232f8cf --- /dev/null +++ b/tests/Browser/ComboboxTest.php @@ -0,0 +1,93 @@ +create([ + 'email' => 'test@example.com', + 'password' => bcrypt('password'), + ]); + + $this->browse(function (Browser $browser) use ($user) { + $browser + ->visit('/admin/login') + ->type('input[type="email"]', $user->email) + ->type('input[type="password"]', 'password') + ->press('Sign in') + ->waitForLocation('/admin') + ->assertSee('Dashboard'); + }); +}); + +test('user can access user resource', function () { + $user = User::factory()->create([ + 'email' => 'admin@example.com', + 'password' => bcrypt('password'), + ]); + + $this->browse(function (Browser $browser) use ($user) { + $browser + ->visit('/admin/login') + ->type('input[type="email"]', $user->email) + ->type('input[type="password"]', 'password') + ->press('Sign in') + ->waitForLocation('/admin') + ->visit('/admin/users') + ->assertSee('Users'); + }); +}); + +test('user can create new user with combobox field', function () { + $user = User::factory()->create([ + 'email' => 'admin@example.com', + 'password' => bcrypt('password'), + ]); + + $this->browse(function (Browser $browser) use ($user) { + $browser + ->visit('/admin/login') + ->type('input[type="email"]', $user->email) + ->type('input[type="password"]', 'password') + ->press('Sign in') + ->waitForLocation('/admin') + ->visit('/admin/users/create') + ->assertSee('Create user') + ->type('input[name="name"]', 'John Doe') + ->type('input[name="email"]', 'john@example.com') + ->screenshot('before-combobox-interaction') + ->click('[data-field-wrapper-id="data.role"]') + ->waitFor('[data-field-wrapper-id="data.role"] [role="listbox"]') + ->screenshot('combobox-dropdown-open') + ->click('[data-field-wrapper-id="data.role"] [role="option"]:first-child') + ->screenshot('combobox-option-selected') + ->type('input[name="password"]', 'password123') + ->press('Create') + ->waitForLocation('/admin/users') + ->screenshot('user-created') + ->assertSee('John Doe'); + }); +}); + +test('combobox field is searchable', function () { + $user = User::factory()->create([ + 'email' => 'admin@example.com', + 'password' => bcrypt('password'), + ]); + + $this->browse(function (Browser $browser) use ($user) { + $browser + ->visit('/admin/login') + ->type('input[type="email"]', $user->email) + ->type('input[type="password"]', 'password') + ->press('Sign in') + ->waitForLocation('/admin') + ->visit('/admin/users/create') + ->click('[data-field-wrapper-id="data.role"]') + ->waitFor('[data-field-wrapper-id="data.role"] input[type="search"]') + ->screenshot('combobox-search-visible') + ->type('[data-field-wrapper-id="data.role"] input[type="search"]', 'admin') + ->screenshot('combobox-search-typed') + ->assertSee('Administrator'); + }); +}); diff --git a/tests/CreatesApplication.php b/tests/CreatesApplication.php new file mode 100644 index 0000000..4ece459 --- /dev/null +++ b/tests/CreatesApplication.php @@ -0,0 +1,68 @@ +make(Kernel::class)->bootstrap(); + + return $app; + } + + protected function getPackageProviders($app) + { + return [ + ActionsServiceProvider::class, + BladeCaptureDirectiveServiceProvider::class, + BladeHeroiconsServiceProvider::class, + BladeIconsServiceProvider::class, + FilamentServiceProvider::class, + FormsServiceProvider::class, + InfolistsServiceProvider::class, + LivewireServiceProvider::class, + NotificationsServiceProvider::class, + SupportServiceProvider::class, + TablesServiceProvider::class, + WidgetsServiceProvider::class, + ComboboxServiceProvider::class, + ]; + } + + protected function getEnvironmentSetUp($app) + { + $app['config']->set('app.key', 'base64:7hJrI1l3H5UBVvEF3dUxHJb2C0dXoP2xC1qiJxz2A/w='); + $app['config']->set('database.default', 'sqlite'); + $app['config']->set('database.connections.sqlite', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + 'prefix' => '', + ]); + $app['config']->set('view.paths', [ + ...$app['config']->get('view.paths', []), + __DIR__.'/../workbench/resources/views', + ]); + } +} diff --git a/tests/DuskTestCase.php b/tests/DuskTestCase.php new file mode 100644 index 0000000..0c65298 --- /dev/null +++ b/tests/DuskTestCase.php @@ -0,0 +1,76 @@ +addArguments(collect([ + '--disable-search-engine-choice-screen', + '--disable-smooth-scrolling', + '--window-size=1920,1080', + ])->merge([ + '--disable-gpu', + '--headless=new', + '--no-sandbox', + '--disable-dev-shm-usage', + ])->all()); + + return RemoteWebDriver::create( + $_ENV['DUSK_DRIVER_URL'] ?? env('DUSK_DRIVER_URL') ?? 'http://localhost:9515', + DesiredCapabilities::chrome()->setCapability( + ChromeOptions::CAPABILITY, $options + ) + ); + } + + protected function baseUrl() + { + return $_ENV['APP_URL'] ?? env('APP_URL') ?? 'http://localhost:8000'; + } + + protected function getPackageProviders($app) + { + return array_merge( + parent::getPackageProviders($app), + [ + WorkbenchServiceProvider::class, + AdminPanelProvider::class, + ] + ); + } +} diff --git a/tests/Pest.php b/tests/Pest.php index a130519..b10a812 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -1,5 +1,7 @@ in(__DIR__); +uses(TestCase::class)->in('.'); +uses(DuskTestCase::class)->in('Browser'); diff --git a/workbench/app/Filament/Resources/UserResource.php b/workbench/app/Filament/Resources/UserResource.php new file mode 100644 index 0000000..106e1a9 --- /dev/null +++ b/workbench/app/Filament/Resources/UserResource.php @@ -0,0 +1,89 @@ +schema([ + Forms\Components\TextInput::make('name') + ->required() + ->maxLength(255), + Forms\Components\TextInput::make('email') + ->email() + ->required() + ->maxLength(255), + Combobox::make('role') + ->label('Role') + ->options([ + 'admin' => 'Administrator', + 'editor' => 'Editor', + 'viewer' => 'Viewer', + ]) + ->searchable() + ->required(), + Forms\Components\TextInput::make('password') + ->password() + ->required() + ->maxLength(255) + ->dehydrateStateUsing(fn ($state) => bcrypt($state)), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('name') + ->searchable(), + Tables\Columns\TextColumn::make('email') + ->searchable(), + Tables\Columns\TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + // + ]) + ->actions([ + Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListUsers::route('/'), + 'create' => Pages\CreateUser::route('/create'), + 'edit' => Pages\EditUser::route('/{record}/edit'), + ]; + } +} diff --git a/workbench/app/Filament/Resources/UserResource/Pages/CreateUser.php b/workbench/app/Filament/Resources/UserResource/Pages/CreateUser.php new file mode 100644 index 0000000..d8f0d8c --- /dev/null +++ b/workbench/app/Filament/Resources/UserResource/Pages/CreateUser.php @@ -0,0 +1,11 @@ + 'datetime', 'password' => 'hashed', ]; + + public function canAccessPanel(Panel $panel): bool + { + return true; + } } diff --git a/workbench/app/Providers/Filament/AdminPanelProvider.php b/workbench/app/Providers/Filament/AdminPanelProvider.php new file mode 100644 index 0000000..b894027 --- /dev/null +++ b/workbench/app/Providers/Filament/AdminPanelProvider.php @@ -0,0 +1,53 @@ +default() + ->id('admin') + ->path('admin') + ->login() + ->colors([ + 'primary' => Color::Amber, + ]) + ->discoverResources(in: app_path('Filament/Resources'), for: 'Workbench\\App\\Filament\\Resources') + ->discoverPages(in: app_path('Filament/Pages'), for: 'Workbench\\App\\Filament\\Pages') + ->pages([ + Pages\Dashboard::class, + ]) + ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'Workbench\\App\\Filament\\Widgets') + ->middleware([ + EncryptCookies::class, + AddQueuedCookiesToResponse::class, + StartSession::class, + AuthenticateSession::class, + ShareErrorsFromSession::class, + VerifyCsrfToken::class, + SubstituteBindings::class, + DisableBladeIconComponents::class, + DispatchServingFilamentEvent::class, + ]) + ->authMiddleware([ + Authenticate::class, + ]); + } +} diff --git a/workbench/app/Providers/WorkbenchServiceProvider.php b/workbench/app/Providers/WorkbenchServiceProvider.php index e8cec9c..dcd5405 100644 --- a/workbench/app/Providers/WorkbenchServiceProvider.php +++ b/workbench/app/Providers/WorkbenchServiceProvider.php @@ -2,7 +2,9 @@ namespace Workbench\App\Providers; +use Illuminate\Support\Facades\Route; use Illuminate\Support\ServiceProvider; +use Workbench\App\Providers\Filament\AdminPanelProvider; class WorkbenchServiceProvider extends ServiceProvider { @@ -11,7 +13,7 @@ class WorkbenchServiceProvider extends ServiceProvider */ public function register(): void { - // + $this->app->register(AdminPanelProvider::class); } /** @@ -19,6 +21,6 @@ public function register(): void */ public function boot(): void { - // + Route::view('/', 'welcome'); } } diff --git a/workbench/database/factories/UserFactory.php b/workbench/database/factories/UserFactory.php index 5920864..9f648f3 100644 --- a/workbench/database/factories/UserFactory.php +++ b/workbench/database/factories/UserFactory.php @@ -36,6 +36,7 @@ public function definition(): array 'email' => fake()->unique()->safeEmail(), 'email_verified_at' => now(), 'password' => static::$password ??= Hash::make('password'), + 'role' => fake()->randomElement(['admin', 'editor', 'viewer']), 'remember_token' => Str::random(10), ]; } diff --git a/workbench/database/migrations/0001_01_01_000010_add_role_to_users_table.php b/workbench/database/migrations/0001_01_01_000010_add_role_to_users_table.php new file mode 100644 index 0000000..2be4164 --- /dev/null +++ b/workbench/database/migrations/0001_01_01_000010_add_role_to_users_table.php @@ -0,0 +1,28 @@ +string('role')->nullable()->after('email'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('role'); + }); + } +}; diff --git a/workbench/database/seeders/DatabaseSeeder.php b/workbench/database/seeders/DatabaseSeeder.php index 1252f3c..6a9afab 100644 --- a/workbench/database/seeders/DatabaseSeeder.php +++ b/workbench/database/seeders/DatabaseSeeder.php @@ -13,11 +13,13 @@ class DatabaseSeeder extends Seeder */ public function run(): void { - // UserFactory::new()->times(10)->create(); + UserFactory::new()->create([ + 'name' => 'Admin User', + 'email' => 'admin@example.com', + 'password' => bcrypt('password'), + 'role' => 'admin', + ]); - // UserFactory::new()->create([ - // 'name' => 'Test User', - // 'email' => 'test@example.com', - // ]); + UserFactory::new()->times(5)->create(); } } diff --git a/workbench/resources/views/welcome.blade.php b/workbench/resources/views/welcome.blade.php new file mode 100644 index 0000000..d66284b --- /dev/null +++ b/workbench/resources/views/welcome.blade.php @@ -0,0 +1,25 @@ + + +
+ + +Welcome to the Filament Combobox test environment.
+ + Go to Admin Panel + +Login credentials:
+Email: admin@example.com
+Password: password
+