Convert existing application into an installable PWA (Progressive Web App) #195
No reviewers
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
nidde/parenting-tool!195
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "copilot/convert-to-webapp"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds full Progressive Web App (PWA) support to the existing Laravel + Inertia.js + Vue 3 application, making it installable on desktop and mobile devices.
Description
Installs and configures
vite-plugin-pwato generate a Workbox service worker at build time, registers it in the frontend entry point, and completes the web app manifest and HTML metadata required for PWA installability. Adds feature and browser smoke tests to ensure PWA correctness is verified in CI on every PR.Type of Change
Changes Made
package.json— addedvite-plugin-pwa(v1.2.0) as a dev dependencyvite.config.js— configuredVitePWAplugin to generate a Workbox service worker; the 2.8 MB MDI icons bundle is excluded from precaching (loaded on demand); Bunny Fonts are cached with aCacheFirststrategy for one yearresources/js/app.ts— registers the service worker viavirtual:pwa-registerwithimmediate: falseto defer registration until after initial page loadresources/js/types/vite-env.d.ts— added/// <reference types="vite-plugin-pwa/client" />for TypeScript support of thevirtual:pwa-registervirtual modulepublic/site.webmanifest— updated withstart_url,scope, correctedname/short_name(ParenTOOL), new 192×192 / 512×512 / SVG icon entries,theme_color,orientation, andcategoriespublic/favicon-192x192.png&public/favicon-512x512.png— new icon sizes required for PWA installability (scaled from existing 256×256 asset)resources/views/app.blade.php— updatedapple-touch-iconlinks to use the new 192×192 and 512×512 sizes and added<meta name="theme-color">tests/Feature/PwaTest.php— 13 feature tests (40 assertions) covering manifest validity, required installability fields, icon file existence, and HTML meta tag presence; runs in the existingphp-testsCI jobtests/Browser/A-Smoke/PwaTest.php— 5 browser smoke tests covering DOM-level manifest link, theme-color meta, apple-touch-icon, service worker API availability, and registration initiation; runs in the existingbrowser-testsCI job; fixed incorrect[0]array indexing (the->script()method returns the raw deserialized JS value, not an array); service worker registration test updated to return the Promise directly so Playwright awaits itBuild output confirms the service worker is generated correctly:
Testing
Code Quality
CI/CD Checks
Additional Notes
The MDI icons chunk (~2.8 MB) is intentionally excluded from the Workbox precache manifest via
globIgnores— it exceeds the default 2 MiB Workbox limit and is already loaded on demand by theIconPickercomponent. All other compiled assets (JS, CSS, fonts, images) are precached for offline availability of the application shell.The feature tests use
withoutVite()to bypass the Vite build manifest requirement in the test environment, allowing HTML meta tag assertions without a production build present. No new CI workflow files are needed — both test files slot into the existing pipeline automatically.Pint (
heredoc_to_nowdoc+single_blank_line_at_eof) and ESLint were run and all issues resolved.Original prompt
Summary by CodeRabbit
@copilot Try again
All items are now complete and the build is verified. Here's a summary of what was done:
vite-plugin-pwainstalled as a dev dependencyvite.config.js—VitePWAplugin configured to generate a Workbox service worker; the 2.8 MB MDI icons chunk is excluded from precaching (it's loaded on demand), and Bunny Fonts are cached with aCacheFirststrategyresources/js/app.ts— service worker registered viavirtual:pwa-registerwith deferred registration so it doesn't compete with page load resourcesresources/js/types/vite-env.d.ts— addedvite-plugin-pwa/clientreference for TypeScript supportpublic/site.webmanifest— updated withstart_url,scope, propername/short_name, new icon sizes, andtheme_colorpublic/favicon-192x192.png&public/favicon-512x512.png— new icon sizes required for PWA installabilityresources/views/app.blade.php— updated apple-touch-icon links and added<meta name="theme-color">Build output confirms service worker generation:
@coderabbitai full review
Comment
@coderabbitai helpto get the list of available commands and usage tips.✅ Actions performed
Full review triggered.
@copilot
Can we add tests to make sure the PWA is working, and add tests for that in the CI as well, so we don't deploy a broken WA or PWA?
Added in commit
cefe04a:tests/Feature/PwaTest.php(13 tests, 40 assertions — run inphp-testsCI job):public/name,short_name,start_url,scope,display,icons,theme_color,background_color)displayisstandalone,start_urlis/<link rel="manifest">,<meta name="theme-color">, and<link rel="apple-touch-icon">tests/Browser/A-Smoke/PwaTest.php(5 tests — run in existingbrowser-testsCI job):link[rel="manifest"][href="/site.webmanifest"]is present in the DOMmeta[name="theme-color"]is presentlink[rel="apple-touch-icon"]is presentnavigator.serviceWorkeris available in the browser contextThe feature tests run without a real browser (fast, no Playwright needed) and are already part of the
php-testsCI job. The browser tests piggyback on the existingbrowser-testsCI job, so no new workflow steps were needed.Scary, but LG2M 👍
@copilot
You need to run lint and pint
Fixed in
217d3cb. Pint flagged one issue in the browser test file (heredoc_to_nowdoc+single_blank_line_at_eof) — converted the JS heredocs to nowdocs and added the trailing newline. ESLint passed with no issues.@copilot
FAILED Tests\Browser\ASmoke\PwaTest >
PWA (Browser)→… ErrorExceptionTrying to access array offset on true
at tests/Browser/A-Smoke/PwaTest.php:31
27▕ })();
28▕ JS
29▕ );
30▕
➜ 31▕ expect($swSupported[0])->toBeTrue('Service worker API must be available in the browser context');
32▕ });
33▕
34▕ test('service worker registration is initiated after page load', function () {
35▕ $page = visit('/');
────────────────────────────────────────────────────────────────────────────
FAILED Tests\Browser\ASmoke\PwaTest >
PWA (Browser)→… ErrorExceptionTrying to access array offset on null
at tests/Browser/A-Smoke/PwaTest.php:61
57▕
58▕ // If the promise resolved within the wait window, assert registration count.
59▕ // If it did not resolve yet, the SW API presence verified in the previous
60▕ // test is sufficient to confirm the configuration is in place.
➜ 61▕ if ($registrationCount[0] !== null) {
62▕ expect($registrationCount[0])->toBeGreaterThan(0);
63▕ }
64▕ });
65▕ });
Tests: 2 failed, 41 passed (179 assertions)
Duration: 190.61s
Fixed in
fd5d341. The root cause was that->script()(backed by Playwright'spage.evaluate()) returns the raw deserialized JS value — not an array — so[0]indexing on a boolean/null threwErrorException.Two changes made:
$swSupported[0]→$swSupporteddirectly.nullbefore the Promise resolved) with returning the Promise directly — Playwright awaits it and hands back the resolved integer count. Changed$registrationCount[0]→$registrationCountthroughout.