Lifecycle testing
How to test an MV3 service worker restart.
Manifest V3 service workers are event-driven and disposable. A test that runs immediately after installation may pass while the same user action fails after Chrome terminates the worker and later starts it again.
The failure this test is designed to reveal
Chrome documents that an extension service worker is normally terminated after inactivity. When it starts again, module-level variables return to their initial values. Event listeners that were registered too late may be absent when the triggering event arrives, and ordinary timers may never finish.
A compact cold-start scenario
- Install the exact release build in a clean profile.
- Complete one critical journey and verify the expected stored state.
- Terminate the extension service worker from the Extensions/DevTools interface or through a controlled test helper.
- Without opening an extension page first, trigger the next real user event: a toolbar action, message, alarm, navigation, or content-script request.
- Verify that the worker starts, reconstructs necessary state, handles the event once, and leaves a visible or stored result.
- Repeat with an interrupted network request and confirm that retry or failure behavior is safe.
Assertions that matter
| Risk | Observable assertion |
|---|---|
| Listener registered asynchronously | The first event after a cold start is handled; it is not necessary to open the popup to initialize the worker. |
| State kept only in a global | The worker reads its source of truth from storage or reconstructs it before responding. |
| Duplicate initialization | One incoming event creates one result, listener, menu item, or injected element. |
| Timer assumed to be durable | Scheduled work is driven by an alarm/event and still occurs after the worker was stopped. |
| Work interrupted during shutdown | The next event detects incomplete work and retries safely or reports a clear recoverable failure. |
Design rules that make the test pass for the right reason
- Register Chrome event listeners synchronously at the top level.
- Use
chrome.storageor another durable store as the source of truth for important state. - Make message handlers idempotent when the same request might be retried.
- Use
chrome.alarmsfor scheduling that must survive worker termination. - Keep initialization small and deterministic; defer optional work until after the triggering event is safe.
- Log enough context to identify the first failed boundary without storing credentials or user data.
Playwright-specific caution
A handle to the extension service worker is useful, but do not make every assertion by evaluating internal variables. Test the visible or persisted outcome whenever possible. If the worker restarts during an in-flight evaluation, the evaluation can fail even though the extension correctly restarts. Treat that as a lifecycle boundary, not automatically as a product failure.
Official references
- Chrome: extension service-worker lifecycle
- Chrome: migrate to a service worker
- Playwright: Chrome extensions
Combine this case with the full release checklist and the Playwright setup guide.
Would you rather record this journey than maintain the harness?
MV3 Replay is validating a local visual workflow that would expose the first divergence and still export readable Playwright. No product or payment exists yet.
Review the concept