Skip to content

Commit cd730e8

Browse files
committed
feat: upgrade to Pest v4 and implement testing improvements
1 parent 9ca719c commit cd730e8

File tree

8 files changed

+301
-9
lines changed

8 files changed

+301
-9
lines changed

.github/workflows/test-runner.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,23 @@ jobs:
1919

2020
runs-on: ubuntu-latest
2121

22-
# Define the matrix of different PHP, Laravel, and testbench versions
22+
# Define the matrix of different PHP, Laravel, testbench versions, and shards
2323
strategy:
2424
# Fail the whole workflow if one of the jobs fails
2525
fail-fast: true
2626
matrix:
2727
php: [ 8.2, 8.3, 8.4 ]
2828
laravel: [ 11.*, 12.* ]
2929
dependency-version: [ prefer-stable ]
30+
shard: [ 1, 2, 3, 4 ]
3031
include:
3132
# Laravel 12 uses Orchestra Testbench 10
3233
- laravel: 12.*
3334
testbench: 10.*
3435
# Laravel 11 uses Orchestra Testbench 9
3536
- laravel: 11.*
3637
testbench: 9.*
37-
name: PHP ${{ matrix.php }} / L${{ matrix.laravel }} / ${{ matrix.dependency-version }}
38+
name: PHP ${{ matrix.php }} / L${{ matrix.laravel }} / ${{ matrix.dependency-version }} / Shard ${{ matrix.shard }}/4
3839

3940
steps:
4041

@@ -61,19 +62,19 @@ jobs:
6162
with:
6263
php-version: ${{ matrix.php }}
6364
coverage: xdebug
64-
# extensions: mbstring, gd, intl
65+
extensions: mbstring, gd, intl, pcntl
6566

6667
- name: Install dependencies
6768
run: |
6869
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update
6970
composer update --${{ matrix.dependency-version }} --prefer-dist --no-progress --no-interaction
7071
7172
- name: Run test suite
72-
run: composer test -- --coverage-clover ./coverage.xml
73+
run: composer test -- --shard=${{ matrix.shard }}/4 --coverage-clover ./coverage.xml
7374

7475
- name: Upload coverage reports to Codecov
7576
# Make sure the Codecov action is only executed once
76-
if: matrix.php == '8.2' && matrix.laravel == '12.*' && matrix.dependency-version == 'prefer-stable'
77+
if: matrix.php == '8.2' && matrix.laravel == '12.*' && matrix.dependency-version == 'prefer-stable' && matrix.shard == 1
7778
uses: codecov/codecov-action@v5
7879
with:
7980
token: ${{ secrets.CODECOV_TOKEN }}

composer.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@
5353
"require-dev": {
5454
"laravel/pint": "^1.21",
5555
"orchestra/testbench": "^9.9|^10.0",
56-
"pestphp/pest": "^3.7",
57-
"pestphp/pest-plugin-livewire": "^3.0"
56+
"pestphp/pest": "^4.0",
57+
"pestphp/pest-plugin-browser": "^4.0",
58+
"pestphp/pest-plugin-laravel": "^4.0",
59+
"pestphp/pest-plugin-livewire": "^4.0"
5860
},
5961
"scripts": {
6062
"post-autoload-dump": [
@@ -64,7 +66,12 @@
6466
"post-install-cmd": "@setup",
6567
"post-update-cmd": "@setup",
6668
"format": "vendor/bin/pint",
67-
"test": "vendor/bin/testbench package:test",
69+
"test": "vendor/bin/testbench package:test --parallel",
70+
"test-shard": "vendor/bin/pest --shard=%SHARD%/%SHARDS%",
71+
"test-shard-1": "vendor/bin/pest --shard=1/4",
72+
"test-shard-2": "vendor/bin/pest --shard=2/4",
73+
"test-shard-3": "vendor/bin/pest --shard=3/4",
74+
"test-shard-4": "vendor/bin/pest --shard=4/4",
6875
"clear": "@php vendor/bin/testbench package:purge-skeleton --ansi",
6976
"prepare": "@php vendor/bin/testbench package:discover --ansi",
7077
"build": "@php vendor/bin/testbench workbench:build --ansi",

package-lock.json

Lines changed: 47 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,8 @@
88
"@commitlint/cli": "^19.7.1",
99
"@commitlint/config-conventional": "^19.7.1",
1010
"husky": "^9.1.7"
11+
},
12+
"dependencies": {
13+
"playwright": "^1.56.1"
1114
}
1215
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
use Eclipse\World\Filament\Clusters\World\Resources\CountryResource;
4+
use Eclipse\World\Models\Country;
5+
use Eclipse\World\Models\Region;
6+
7+
beforeEach(function () {
8+
$this->setUpSuperAdmin();
9+
});
10+
11+
test('can browse country resource page', function () {
12+
$region = Region::factory()->create(['name' => 'Test Region']);
13+
$country = Country::factory()->create([
14+
'name' => 'Test Country',
15+
'id' => 'TC',
16+
'region_id' => $region->id,
17+
]);
18+
19+
$this->visit(CountryResource::getUrl())
20+
->assertSee('Countries')
21+
->assertSee('Test Country')
22+
->assertSee('TC')
23+
->assertSee('Test Region');
24+
});
25+
26+
test('can interact with country resource table', function () {
27+
$region = Region::factory()->create(['name' => 'Browser Test Region']);
28+
$country = Country::factory()->create([
29+
'name' => 'Browser Test Country',
30+
'id' => 'BTC',
31+
'region_id' => $region->id,
32+
]);
33+
34+
$this->visit(CountryResource::getUrl())
35+
->assertSee('Browser Test Country')
36+
->assertSee('BTC')
37+
->assertSee('Browser Test Region')
38+
->assertSee('Countries');
39+
});
40+
41+
test('country resource page loads without JavaScript errors', function () {
42+
$this->visit(CountryResource::getUrl())
43+
->assertSee('Countries')
44+
->assertDontSee('Uncaught')
45+
->assertDontSee('ReferenceError')
46+
->assertDontSee('TypeError')
47+
->assertDontSee('SyntaxError');
48+
});
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
use Eclipse\World\Filament\Clusters\World\Resources\CountryResource;
4+
use Eclipse\World\Filament\Clusters\World\Resources\CurrencyResource;
5+
use Eclipse\World\Filament\Clusters\World\Resources\PostResource;
6+
use Eclipse\World\Filament\Clusters\World\Resources\RegionResource;
7+
use Eclipse\World\Models\Country;
8+
use Eclipse\World\Models\Region;
9+
10+
beforeEach(function () {
11+
$this->setUpSuperAdmin();
12+
});
13+
14+
describe('Visual Regression Tests', function () {
15+
test('country resource page visual regression', function () {
16+
$region = Region::factory()->create(['name' => 'Visual Test Region']);
17+
$country = Country::factory()->create([
18+
'name' => 'Visual Test Country',
19+
'id' => 'VT',
20+
'a3_id' => 'VTC',
21+
'num_code' => '999',
22+
'flag' => '🏳️',
23+
'region_id' => $region->id,
24+
]);
25+
26+
$this->visit(CountryResource::getUrl())
27+
->assertSee('Countries')
28+
->assertSee('Visual Test Country')
29+
->wait(1)
30+
->assertScreenshotMatches();
31+
});
32+
33+
test('currency resource page visual regression', function () {
34+
$this->visit(CurrencyResource::getUrl())
35+
->assertSee('Currencies')
36+
->wait(1)
37+
->assertScreenshotMatches();
38+
});
39+
40+
test('post resource page visual regression', function () {
41+
$this->visit(PostResource::getUrl())
42+
->assertSee('Posts')
43+
->wait(1)
44+
->assertScreenshotMatches();
45+
});
46+
47+
test('region resource page visual regression', function () {
48+
$this->visit(RegionResource::getUrl())
49+
->assertSee('Regions')
50+
->wait(1)
51+
->assertScreenshotMatches();
52+
});
53+
54+
test('country resource page with data visual regression', function () {
55+
$region1 = Region::factory()->create(['name' => 'Europe']);
56+
$region2 = Region::factory()->create(['name' => 'Asia']);
57+
58+
Country::factory()->create([
59+
'name' => 'Germany',
60+
'id' => 'DE',
61+
'a3_id' => 'DEU',
62+
'num_code' => '276',
63+
'flag' => '🇩🇪',
64+
'region_id' => $region1->id,
65+
]);
66+
67+
Country::factory()->create([
68+
'name' => 'Japan',
69+
'id' => 'JP',
70+
'a3_id' => 'JPN',
71+
'num_code' => '392',
72+
'flag' => '🇯🇵',
73+
'region_id' => $region2->id,
74+
]);
75+
76+
Country::factory()->create([
77+
'name' => 'United States',
78+
'id' => 'US',
79+
'a3_id' => 'USA',
80+
'num_code' => '840',
81+
'flag' => '🇺🇸',
82+
'region_id' => $region1->id,
83+
]);
84+
85+
$this->visit(CountryResource::getUrl())
86+
->assertSee('Countries')
87+
->assertSee('Germany')
88+
->assertSee('Japan')
89+
->assertSee('United States')
90+
->wait(1)
91+
->assertScreenshotMatches();
92+
});
93+
});

tests/Feature/SmokeTest.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
use Eclipse\World\Filament\Clusters\World\Resources\CountryResource;
4+
use Eclipse\World\Filament\Clusters\World\Resources\CurrencyResource;
5+
use Eclipse\World\Filament\Clusters\World\Resources\PostResource;
6+
use Eclipse\World\Filament\Clusters\World\Resources\RegionResource;
7+
8+
beforeEach(function () {
9+
$this->setUpSuperAdmin();
10+
});
11+
12+
describe('Smoke Tests', function () {
13+
test('all resource URLs are accessible', function () {
14+
$resources = [
15+
CountryResource::class,
16+
CurrencyResource::class,
17+
PostResource::class,
18+
RegionResource::class,
19+
];
20+
21+
foreach ($resources as $resource) {
22+
$this->get($resource::getUrl())
23+
->assertSuccessful()
24+
->assertSee('Filament');
25+
}
26+
});
27+
28+
test('country resource URLs are accessible', function () {
29+
$this->get(CountryResource::getUrl())
30+
->assertSuccessful()
31+
->assertSee('Countries')
32+
->assertSee('Filament');
33+
});
34+
35+
test('currency resource URLs are accessible', function () {
36+
$this->get(CurrencyResource::getUrl())
37+
->assertSuccessful()
38+
->assertSee('Currencies')
39+
->assertSee('Filament');
40+
});
41+
42+
test('post resource URLs are accessible', function () {
43+
$this->get(PostResource::getUrl())
44+
->assertSuccessful()
45+
->assertSee('Posts')
46+
->assertSee('Filament');
47+
});
48+
49+
test('region resource URLs are accessible', function () {
50+
$this->get(RegionResource::getUrl())
51+
->assertSuccessful()
52+
->assertSee('Regions')
53+
->assertSee('Filament');
54+
});
55+
56+
test('all resource URLs return valid HTML', function () {
57+
$resources = [
58+
CountryResource::class,
59+
CurrencyResource::class,
60+
PostResource::class,
61+
RegionResource::class,
62+
];
63+
64+
foreach ($resources as $resource) {
65+
$response = $this->get($resource::getUrl());
66+
67+
$response->assertSuccessful();
68+
$response->assertHeader('content-type', 'text/html; charset=UTF-8');
69+
$response->assertSee('<!DOCTYPE html>', false);
70+
}
71+
});
72+
73+
test('all resource URLs have no JavaScript errors', function () {
74+
$resources = [
75+
CountryResource::class,
76+
CurrencyResource::class,
77+
PostResource::class,
78+
RegionResource::class,
79+
];
80+
81+
foreach ($resources as $resource) {
82+
$response = $this->get($resource::getUrl());
83+
84+
$response->assertSuccessful();
85+
$response->assertDontSee('Uncaught');
86+
$response->assertDontSee('ReferenceError');
87+
$response->assertDontSee('TypeError');
88+
}
89+
});
90+
});

tests/TestCase.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ protected function migrate(): self
4040
*/
4141
protected function setUpSuperAdmin(): self
4242
{
43-
$this->superAdmin = User::factory()->create();
43+
$this->superAdmin = User::factory()->create([
44+
'name' => 'Test Super Admin',
45+
'email' => '[email protected]',
46+
]);
4447

4548
// Assign super admin role and give all permissions
4649
$superAdminRole = \Spatie\Permission\Models\Role::where('name', 'super_admin')->first();

0 commit comments

Comments
 (0)