diff --git a/packages/workbox-window/Workbox.mjs b/packages/workbox-window/Workbox.mjs index d1ece2ea8..4a1472709 100644 --- a/packages/workbox-window/Workbox.mjs +++ b/packages/workbox-window/Workbox.mjs @@ -220,7 +220,9 @@ class Workbox extends EventTargetShim { * @return {Promise} */ async getSW() { - return this._swDeferred.promise; + // If `this._sw` is set, resolve with that as we want `getSW()` to + // return the correct (new) service worker if an update is found. + return this._sw || this._swDeferred.promise; } /** diff --git a/test/workbox-window/unit/test-Workbox.mjs b/test/workbox-window/unit/test-Workbox.mjs index 5ba6aad10..c7175862b 100644 --- a/test/workbox-window/unit/test-Workbox.mjs +++ b/test/workbox-window/unit/test-Workbox.mjs @@ -403,6 +403,35 @@ describe(`[workbox-window] Workbox`, function() { const sw = await wb.getSW(); expect(sw.state).to.equal('installing'); }); + + it(`resolves to the new SW after an update is found`, async function() { + const scriptURL = navigator.serviceWorker.controller.scriptURL; + + // Update the SW after it's controlling so both an original compatible + // controller is found **and** and update is found. We need to assert + // that the `getSW()` method resolves to the correct SW in both cases. + await updateVersion('2.0.0', scriptURL); + + const wb = new Workbox(scriptURL); + + // Registering using the same script URL that's already active won't + // trigger an update. + const regPromise = wb.register(); + + const controllingSW = await wb.getSW(); + expect(controllingSW).to.equal(navigator.serviceWorker.controller); + + const reg = await regPromise; + + // Force an update check. + reg.update(); + + await nextEvent(wb, 'controlling'); + + const installedSW = await wb.getSW(); + expect(installedSW).to.equal(reg.active); + expect(installedSW).to.not.equal(controllingSW); + }); }); describe(`messageSW`, function() {