diff --git a/infra/testing/activate-and-control.js b/infra/testing/activate-and-control.js new file mode 100644 index 000000000..c5159a7ef --- /dev/null +++ b/infra/testing/activate-and-control.js @@ -0,0 +1,66 @@ +const activateSWSafari = require('./activate-sw-safari'); + +module.exports = async (swUrl) => { + if (global.__workbox.seleniumBrowser.getId() === 'safari') { + return activateSWSafari(swUrl); + } + + const error = await global.__workbox.webdriver.executeAsyncScript((swUrl, cb) => { + function _onStateChangePromise(registration, desiredState) { + return new Promise((resolve, reject) => { + if (registration.installing === null) { + throw new Error('Service worker is not installing.'); + } + + let serviceWorker = registration.installing; + + // We unregister all service workers after each test - this should + // always trigger an install state change + let stateChangeListener = function(evt) { + if (evt.target.state === desiredState) { + serviceWorker.removeEventListener('statechange', stateChangeListener); + resolve(); + return; + } + + if (evt.target.state === 'redundant') { + serviceWorker.removeEventListener('statechange', stateChangeListener); + + // Must call reject rather than throw error here due to this + // being inside the scope of the callback function stateChangeListener + reject(new Error('Installing servier worker became redundant')); + return; + } + }; + + serviceWorker.addEventListener('statechange', stateChangeListener); + }); + } + + navigator.serviceWorker.register(swUrl) + .then((registration) => { + return _onStateChangePromise(registration, 'activated'); + }) + .then(() => { + // Ensure the page is being controlled by the SW. + if (navigator.serviceWorker.controller && + navigator.serviceWorker.controller.scriptURL === swUrl) { + return; + } else { + return new Promise((resolve) => { + navigator.serviceWorker.addEventListener('controllerchange', () => { + if (navigator.serviceWorker.controller.scriptURL === swUrl) { + resolve(); + } + }); + }); + } + }) + .then(() => cb()) + .catch((err) => cb(err)); + }, swUrl); + + if (error) { + throw error; + } +}; diff --git a/infra/testing/activate-sw.js b/infra/testing/activate-sw.js deleted file mode 100644 index 402c2c1ae..000000000 --- a/infra/testing/activate-sw.js +++ /dev/null @@ -1,25 +0,0 @@ -const activateSWSafari = require('./activate-sw-safari'); - -module.exports = async (swUrl) => { - if (global.__workbox.seleniumBrowser.getId() === 'safari') { - return activateSWSafari(swUrl); - } - - const error = await global.__workbox.webdriver.executeAsyncScript((swUrl, cb) => { - if (navigator.serviceWorker.controller && - navigator.serviceWorker.controller.scriptURL === swUrl) { - cb(); - } else { - navigator.serviceWorker.addEventListener('controllerchange', () => { - if (navigator.serviceWorker.controller.scriptURL === swUrl) { - cb(); - } - }); - navigator.serviceWorker.register(swUrl).catch((error) => cb(error)); - } - }, swUrl); - - if (error) { - throw error; - } -}; diff --git a/packages/workbox-precaching/_default.mjs b/packages/workbox-precaching/_default.mjs index 100033a41..ac62b6364 100644 --- a/packages/workbox-precaching/_default.mjs +++ b/packages/workbox-precaching/_default.mjs @@ -165,7 +165,7 @@ moduleExports.precache = (entries) => { })); }); self.addEventListener('activate', (event) => { - event.waitUntil(precacheController.cleanup()); + event.waitUntil(precacheController.activate()); }); }; diff --git a/packages/workbox-precaching/controllers/PrecacheController.mjs b/packages/workbox-precaching/controllers/PrecacheController.mjs index cca8c36a9..f47d79db8 100644 --- a/packages/workbox-precaching/controllers/PrecacheController.mjs +++ b/packages/workbox-precaching/controllers/PrecacheController.mjs @@ -164,11 +164,15 @@ class PrecacheController { } } + // Clear any existing temp cache + await caches.delete(this._getTempCacheName()); + const entriesToPrecache = []; const entriesAlreadyPrecached = []; for (const precacheEntry of this._entriesToCacheMap.values()) { - if (await this._precacheDetailsModel._isEntryCached(precacheEntry)) { + if (await this._precacheDetailsModel._isEntryCached( + this._cacheName, precacheEntry)) { entriesAlreadyPrecached.push(precacheEntry); } else { entriesToPrecache.push(precacheEntry); @@ -177,7 +181,7 @@ class PrecacheController { // Wait for all requests to be cached. await Promise.all(entriesToPrecache.map((precacheEntry) => { - return this._cacheEntry(precacheEntry, options.plugins); + return this._cacheEntryInTemp(precacheEntry, options.plugins); })); if (process.env.NODE_ENV !== 'production') { @@ -190,6 +194,41 @@ class PrecacheController { }; } + /** + * Takes the current set of temporary files and moves them to the final + * cache, deleting the temporary cache once copying is complete. + * + * @return { + * Promise} + * Resolves with an object containing details of the deleted cache requests + * and precache revision details. + */ + async activate() { + const tempCache = await caches.open(this._getTempCacheName()); + + const requests = await tempCache.keys(); + await Promise.all(requests.map(async (request) => { + const response = await tempCache.match(request); + await cacheWrapper.put(this._cacheName, request, response); + await tempCache.delete(request); + })); + + await caches.delete(this._getTempCacheName()); + + return this._cleanup(); + } + + /** + * Returns the name of the temporary cache. + * + * @return {string} + * + * @private + */ + _getTempCacheName() { + return `${this._cacheName}-temp`; + } + /** * Requests the entry and saves it to the cache if the response * is valid. @@ -203,7 +242,7 @@ class PrecacheController { * promise resolves with true if the entry was cached / updated and * false if the entry is already cached and up-to-date. */ - async _cacheEntry(precacheEntry, plugins) { + async _cacheEntryInTemp(precacheEntry, plugins) { let response = await fetchWrapper.fetch( precacheEntry._networkRequest, null, @@ -214,7 +253,7 @@ class PrecacheController { response = await cleanRedirect(response); } - await cacheWrapper.put(this._cacheName, + await cacheWrapper.put(this._getTempCacheName(), precacheEntry._cacheRequest, response, plugins); await this._precacheDetailsModel._addEntry(precacheEntry); @@ -232,8 +271,10 @@ class PrecacheController { * Promise} * Resolves with an object containing details of the deleted cache requests * and precache revision details. + * + * @private */ - async cleanup() { + async _cleanup() { const expectedCacheUrls = []; this._entriesToCacheMap.forEach((entry) => { const fullUrl = new URL(entry._cacheRequest.url, location).toString(); diff --git a/packages/workbox-precaching/models/PrecachedDetailsModel.mjs b/packages/workbox-precaching/models/PrecachedDetailsModel.mjs index 5694cc800..30cd7c8bf 100644 --- a/packages/workbox-precaching/models/PrecachedDetailsModel.mjs +++ b/packages/workbox-precaching/models/PrecachedDetailsModel.mjs @@ -15,7 +15,6 @@ */ import {DBWrapper} from 'workbox-core/_private/DBWrapper.mjs'; -import {cacheNames} from 'workbox-core/_private/cacheNames.mjs'; import '../_version.mjs'; // Allows minifier to mangle this name @@ -32,12 +31,9 @@ class PrecachedDetailsModel { /** * Construct a new model for a specific cache. * - * @param {string} cacheName - * * @private */ - constructor(cacheName) { - this._cacheName = cacheNames.getPrecacheName(cacheName); + constructor() { this._db = new DBWrapper(`workbox-precaching`, 2, { onupgradeneeded: this._handleUpgrade, }); @@ -70,18 +66,19 @@ class PrecachedDetailsModel { * Check if an entry is already cached. Returns false if * the entry isn't cached or the revision has changed. * + * @param {string} cacheName * @param {PrecacheEntry} precacheEntry * @return {boolean} * * @private */ - async _isEntryCached(precacheEntry) { + async _isEntryCached(cacheName, precacheEntry) { const revisionDetails = await this._getRevision(precacheEntry._entryId); if (revisionDetails !== precacheEntry._revision) { return false; } - const openCache = await caches.open(this._cacheName); + const openCache = await caches.open(cacheName); const cachedResponse = await openCache.match(precacheEntry._cacheRequest); return !!cachedResponse; } diff --git a/test/workbox-background-sync/integration/test-bg-sync.js b/test/workbox-background-sync/integration/test-bg-sync.js index 11b1f5779..8918f0696 100644 --- a/test/workbox-background-sync/integration/test-bg-sync.js +++ b/test/workbox-background-sync/integration/test-bg-sync.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe(`[workbox-background-sync] Load and use Background Sync`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -27,7 +27,7 @@ describe(`[workbox-background-sync] Load and use Background Sync`, function() { it(`should load a page with service worker`, async function() { // Load the page and wait for the first service worker to register and activate. await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); const err = await global.__workbox.webdriver.executeAsyncScript((testingUrl, cb) => { return fetch(`${testingUrl}example.txt`) diff --git a/test/workbox-broadcast-cache-update/integration/broadcast-cache-update-plugin.js b/test/workbox-broadcast-cache-update/integration/broadcast-cache-update-plugin.js index b6053b8be..b6c94f839 100644 --- a/test/workbox-broadcast-cache-update/integration/broadcast-cache-update-plugin.js +++ b/test/workbox-broadcast-cache-update/integration/broadcast-cache-update-plugin.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe(`broadcastCacheUpdate.Plugin`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -10,7 +10,7 @@ describe(`broadcastCacheUpdate.Plugin`, function() { it(`should broadcast a message on the expected channel when there's a cache update`, async function() { await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); const supported = await global.__workbox.webdriver.executeScript(() => { return 'BroadcastChannel' in window; diff --git a/test/workbox-cache-expiration/integration/expiration-plugin.js b/test/workbox-cache-expiration/integration/expiration-plugin.js index 159d28eca..08a8b3b88 100644 --- a/test/workbox-cache-expiration/integration/expiration-plugin.js +++ b/test/workbox-cache-expiration/integration/expiration-plugin.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); const cleanSWEnv = require('../../../infra/testing/clean-sw'); describe(`expiration.Plugin`, function() { @@ -30,7 +30,7 @@ describe(`expiration.Plugin`, function() { const swUrl = `${testingUrl}sw-max-entries.js`; // Wait for the service worker to register and activate. - await activateSW(swUrl); + await activateAndControlSW(swUrl); await global.__workbox.webdriver.executeAsyncScript((testingUrl, cb) => { fetch(`${testingUrl}example-1.txt`).then(() => cb()).catch((err) => cb(err.message)); @@ -86,7 +86,7 @@ describe(`expiration.Plugin`, function() { // Load the page and wait for the service worker to register and activate. await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); await global.__workbox.webdriver.executeAsyncScript((testingUrl, cb) => { fetch(`${testingUrl}example-1.txt`).then(() => cb()).catch((err) => cb(err.message)); diff --git a/test/workbox-cacheable-response/integration/test-cacheable-response-plugin.js b/test/workbox-cacheable-response/integration/test-cacheable-response-plugin.js index c109eeccd..bf7c50da8 100644 --- a/test/workbox-cacheable-response/integration/test-cacheable-response-plugin.js +++ b/test/workbox-cacheable-response/integration/test-cacheable-response-plugin.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe(`cacheableResponse.Plugin`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -33,7 +33,7 @@ describe(`cacheableResponse.Plugin`, function() { it(`should load a page and cache entries`, async function() { // Wait for the service worker to register and activate. - await activateSW(swUrl); + await activateAndControlSW(swUrl); await global.__workbox.webdriver.executeAsyncScript((testingUrl, cb) => { fetch(`${testingUrl}example-1.txt`).then(() => cb()).catch((err) => cb(err.message)); diff --git a/test/workbox-core/integration/test-core.js b/test/workbox-core/integration/test-core.js index 60d527ee2..7bf8a57a7 100644 --- a/test/workbox-core/integration/test-core.js +++ b/test/workbox-core/integration/test-core.js @@ -1,4 +1,4 @@ -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe(`[workbox-core] Load core in the browser`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -7,7 +7,7 @@ describe(`[workbox-core] Load core in the browser`, function() { it(`should load workbox-core in a service worker.`, async function() { await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); // If the service worker activated, it meant the assertions in sw.js were // met and workbox-core exposes the expected API and defaults that were diff --git a/test/workbox-google-analytics/integration/basic-example.js b/test/workbox-google-analytics/integration/basic-example.js index 767009fc0..4dc52ca5a 100644 --- a/test/workbox-google-analytics/integration/basic-example.js +++ b/test/workbox-google-analytics/integration/basic-example.js @@ -1,7 +1,7 @@ const expect = require('chai').expect; const qs = require('qs'); const {By} = require('selenium-webdriver'); -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe(`[workbox-google-analytics] Load and use Google Analytics`, function() { @@ -27,11 +27,14 @@ describe(`[workbox-google-analytics] Load and use Google Analytics`, data, [messageChannel.port2]); }; - beforeEach(async function() { + before(async function() { // Load the page and wait for the first service worker to activate. await driver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); + }); + + beforeEach(async function() { // Reset the spied requests array. await driver.executeAsyncScript(messageSw, { action: 'clear-spied-requests', diff --git a/test/workbox-precaching/integration/precache-and-update.js b/test/workbox-precaching/integration/precache-and-update.js index 19494c722..62be8d249 100644 --- a/test/workbox-precaching/integration/precache-and-update.js +++ b/test/workbox-precaching/integration/precache-and-update.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); const cleanSWEnv = require('../../../infra/testing/clean-sw'); describe(`[workbox-precaching] Precache and Update`, function() { @@ -30,6 +30,8 @@ describe(`[workbox-precaching] Precache and Update`, function() { const SW_1_URL = `${testingUrl}sw-1.js`; const SW_2_URL = `${testingUrl}sw-2.js`; + await global.__workbox.webdriver.get(testingUrl); + const getIdbData = global.__workbox.seleniumBrowser.getId() === 'safari' ? require('../utils/getPrecachedIDBData-safari') : require('../utils/getPrecachedIDBData'); @@ -43,7 +45,7 @@ describe(`[workbox-precaching] Precache and Update`, function() { global.__workbox.server.reset(); // Register the first service worker. - await activateSW(SW_1_URL); + await activateAndControlSW(SW_1_URL); // Check that only the precache cache was created. const keys = await global.__workbox.webdriver.executeAsyncScript((cb) => { @@ -104,7 +106,7 @@ describe(`[workbox-precaching] Precache and Update`, function() { } // Activate the second service worker - await activateSW(SW_2_URL); + await activateAndControlSW(SW_2_URL); // Ensure that the new assets were requested and cache busted. requestsMade = global.__workbox.server.getRequests(); @@ -139,6 +141,7 @@ describe(`[workbox-precaching] Precache and Update`, function() { // Refresh the page and test that the requests are as expected global.__workbox.server.reset(); await global.__workbox.webdriver.get(testingUrl); + requestsMade = global.__workbox.server.getRequests(); // Ensure the HTML page is returned from cache and not network expect(requestsMade['/test/workbox-precaching/static/precache-and-update/']).to.equal(undefined); diff --git a/test/workbox-precaching/node/controllers/test-PrecacheController.mjs b/test/workbox-precaching/node/controllers/test-PrecacheController.mjs index c3abe2aa2..22edf985a 100644 --- a/test/workbox-precaching/node/controllers/test-PrecacheController.mjs +++ b/test/workbox-precaching/node/controllers/test-PrecacheController.mjs @@ -239,8 +239,7 @@ describe(`[workbox-precaching] PrecacheController`, function() { expect(updateInfo.updatedEntries.length).to.equal(cacheList.length); expect(updateInfo.notUpdatedEntries.length).to.equal(0); - - const cache = await caches.open(cacheNames.getPrecacheName()); + const cache = await caches.open(`${cacheNames.getPrecacheName()}-temp`); const keys = await cache.keys(); expect(keys.length).to.equal(cacheList.length); @@ -298,7 +297,7 @@ describe(`[workbox-precaching] PrecacheController`, function() { precacheController.addToCacheList(cacheList); await precacheController.install(); - const cache = await caches.open(`test-cache-name`); + const cache = await caches.open(`test-cache-name-temp`); const keys = await cache.keys(); expect(keys.length).to.equal(cacheList.length); @@ -309,8 +308,6 @@ describe(`[workbox-precaching] PrecacheController`, function() { }); it('should only precache assets that have changed', async function() { - const cache = await caches.open(cacheNames.getPrecacheName()); - /* First precache some entries */ @@ -321,6 +318,8 @@ describe(`[workbox-precaching] PrecacheController`, function() { {url: '/scripts/index.js', revision: '1234'}, {url: '/scripts/stress.js?test=search&foo=bar', revision: '1234'}, ]; + const urlsListOne = cacheListOne.map((entry) => entry.url || entry); + precacheControllerOne.addToCacheList(cacheListOne); // Reset as addToCacheList will log. @@ -330,20 +329,43 @@ describe(`[workbox-precaching] PrecacheController`, function() { expect(updateInfo.updatedEntries.length).to.equal(cacheListOne.length); expect(updateInfo.notUpdatedEntries.length).to.equal(0); - const keysOne = await cache.keys(); - expect(keysOne.length).to.equal(cacheListOne.length); - - const urlsOne = cacheListOne.map((entry) => entry.url || entry); - await Promise.all(urlsOne.map(async (url) => { - const cachedResponse = await cache.match(url); - expect(cachedResponse).to.exist; - })); - if (process.env.NODE_ENV != 'production') { // Make sure we print some debug info. expect(logger.log.callCount).to.be.gt(0); } + const tempCacheName = `${cacheNames.getPrecacheName()}-temp`; + let tempCache = await caches.open(tempCacheName); + let finalCache = await caches.open(cacheNames.getPrecacheName()); + + // Make sure the files are cached in the temp cache and no the final cache + const tempKeysOne = await tempCache.keys(); + const finalCacheKeysOne = await finalCache.keys(); + expect(tempKeysOne.length).to.equal(cacheListOne.length); + expect(finalCacheKeysOne.length).to.equal(0); + + await Promise.all(urlsListOne.map(async (url) => { + const cachedResponse = await tempCache.match(url); + expect(cachedResponse).to.exist; + })); + + await precacheControllerOne.activate(); + + // Ensure temp cache is deleted + let availableCaches = await caches.keys(); + expect(availableCaches.indexOf(tempCacheName)).to.equal(-1); + + // The cache mock needs the cache to be re-opened to have up-to-date keys. + finalCache = await caches.open(cacheNames.getPrecacheName()); + const finalCacheKeysOneActivate = await finalCache.keys(); + expect(finalCacheKeysOneActivate.length).to.equal(cacheListOne.length); + + // Make sure the files are cached in the final cache + await Promise.all(urlsListOne.map(async (url) => { + const cachedResponse = await finalCache.match(url); + expect(cachedResponse).to.exist; + })); + /* THEN precache the same URLs but two with different revisions */ @@ -354,6 +376,8 @@ describe(`[workbox-precaching] PrecacheController`, function() { {url: '/scripts/index.js', revision: '1234'}, {url: '/scripts/stress.js?test=search&foo=bar', revision: '4321'}, ]; + const urlsListTwo = cacheListTwo.map((entry) => entry.url || entry); + precacheControllerTwo.addToCacheList(cacheListTwo); // Reset as addToCacheList will log. @@ -363,17 +387,25 @@ describe(`[workbox-precaching] PrecacheController`, function() { expect(updateInfoTwo.updatedEntries.length).to.equal(2); expect(updateInfoTwo.notUpdatedEntries.length).to.equal(2); - const keysTwo = await cache.keys(); - // Precaching can't determine that 'index.1234.html' and 'index.4321.html' - // represent the same URL, so the cache ould contain both at this point - // since they are technically different URLs + // The cache mock needs the cache to be re-opened to have up-to-date keys. + tempCache = await caches.open(`${cacheNames.getPrecacheName()}-temp`); + finalCache = await caches.open(cacheNames.getPrecacheName()); + + const tempKeysTwo = await tempCache.keys(); + const finalKeysTwo = await finalCache.keys(); + + // Temp cache will contain the two new URLs that need to be cached. + // The final cache should be untouched until the activate step. // It would be in the activate event that 'index.1234.html' would // be removed from the cache and indexedDB. - expect(keysTwo.length).to.equal(cacheListTwo.length + 1); - - const urlsTwo = cacheListTwo.map((entry) => entry.url || entry); - await Promise.all(urlsTwo.map(async (url) => { - const cachedResponse = await cache.match(url); + expect(tempKeysTwo.length).to.equal(updateInfoTwo.updatedEntries.length); + expect(finalKeysTwo.length).to.equal(cacheListOne.length); + await Promise.all(updateInfoTwo.updatedEntries.map(async (precacheEntry) => { + const cachedResponse = await tempCache.match(precacheEntry._cacheRequest); + expect(cachedResponse).to.exist; + })); + await Promise.all(urlsListOne.map(async (url) => { + const cachedResponse = await finalCache.match(url); expect(cachedResponse).to.exist; })); @@ -381,6 +413,21 @@ describe(`[workbox-precaching] PrecacheController`, function() { // Make sure we print some debug info. expect(logger.log.callCount).to.be.gt(0); } + + await precacheControllerTwo.activate(); + + // Ensure temp cache is deleted + availableCaches = await caches.keys(); + expect(availableCaches.indexOf(tempCacheName)).to.equal(-1); + + // Cache mock needs this to update keys + finalCache = await caches.open(cacheNames.getPrecacheName()); + const finalKeysTwoActivate = await finalCache.keys(); + expect(finalKeysTwoActivate.length).to.equal(urlsListTwo.length); + await Promise.all(urlsListTwo.map(async (url) => { + const cachedResponse = await finalCache.match(url); + expect(cachedResponse).to.exist; + })); }); it('it should precache with plugins', async function() { @@ -425,7 +472,7 @@ describe(`[workbox-precaching] PrecacheController`, function() { }); }); - describe(`cleanup()`, function() { + describe(`activate()`, function() { it(`should remove out of date entry`, async function() { const cache = await caches.open(cacheNames.getPrecacheName()); @@ -439,7 +486,7 @@ describe(`[workbox-precaching] PrecacheController`, function() { precacheControllerOne.addToCacheList(cacheListOne); await precacheControllerOne.install(); - const cleanupDetailsOne = await precacheControllerOne.cleanup(); + const cleanupDetailsOne = await precacheControllerOne.activate(); expect(cleanupDetailsOne.deletedCacheRequests.length).to.equal(0); expect(cleanupDetailsOne.deletedRevisionDetails.length).to.equal(0); @@ -448,7 +495,7 @@ describe(`[workbox-precaching] PrecacheController`, function() { precacheControllerTwo.addToCacheList(cacheListTwo); await precacheControllerTwo.install(); - const cleanupDetailsTwo = await precacheControllerTwo.cleanup(); + const cleanupDetailsTwo = await precacheControllerTwo.activate(); expect(cleanupDetailsTwo.deletedCacheRequests.length).to.equal(1); expect(cleanupDetailsTwo.deletedCacheRequests[0]).to.equal('/scripts/index.js'); expect(cleanupDetailsTwo.deletedRevisionDetails.length).to.equal(1); @@ -480,7 +527,7 @@ describe(`[workbox-precaching] PrecacheController`, function() { // Reset as addToCacheList and install will log. logger.log.reset(); - const cleanupDetailsOne = await precacheControllerOne.cleanup(); + const cleanupDetailsOne = await precacheControllerOne.activate(); expect(cleanupDetailsOne.deletedCacheRequests.length).to.equal(0); expect(cleanupDetailsOne.deletedRevisionDetails.length).to.equal(0); @@ -503,7 +550,7 @@ describe(`[workbox-precaching] PrecacheController`, function() { // Reset as addToCacheList and install will log. logger.log.reset(); - const cleanupDetailsTwo = await precacheControllerTwo.cleanup(); + const cleanupDetailsTwo = await precacheControllerTwo.activate(); expect(cleanupDetailsTwo.deletedCacheRequests.length).to.equal(1); expect(cleanupDetailsTwo.deletedCacheRequests[0]).to.equal('/index.1234.html'); expect(cleanupDetailsTwo.deletedRevisionDetails.length).to.equal(1); @@ -567,9 +614,9 @@ describe(`[workbox-precaching] PrecacheController`, function() { } }); - it(`shouldn't open / create a cache when performing cleanup`, async function() { + it(`shouldn't open / create a cache when performing activate`, async function() { const precacheController = new PrecacheController(); - await precacheController.cleanup(); + await precacheController.activate(); const hasCache = await caches.has(cacheNames.getPrecacheName()); expect(hasCache).to.equal(false); @@ -585,7 +632,7 @@ describe(`[workbox-precaching] PrecacheController`, function() { ]; precacheControllerOne.addToCacheList(cacheListOne); await precacheControllerOne.install(); - await precacheControllerOne.cleanup(); + await precacheControllerOne.activate(); const precacheControllerTwo = new PrecacheController(); const cacheListTwo = [ @@ -600,7 +647,7 @@ describe(`[workbox-precaching] PrecacheController`, function() { // Reset as addToCacheList and install will log. logger.log.reset(); - await precacheControllerTwo.cleanup(); + await precacheControllerTwo.activate(); // Make sure we didn't print any debug info. expect(logger.log.callCount).to.equal(0); diff --git a/test/workbox-precaching/node/controllers/test-default.mjs b/test/workbox-precaching/node/controllers/test-default.mjs index 482e63478..1b1e5d462 100644 --- a/test/workbox-precaching/node/controllers/test-default.mjs +++ b/test/workbox-precaching/node/controllers/test-default.mjs @@ -34,13 +34,13 @@ describe(`[workbox-precaching] default export`, function() { expect(self.addEventListener.args[1][0]).to.equal('activate'); }); - it(`should call install and cleanup on install and activate`, async function() { + it(`should call install and activate on install and activate`, async function() { let eventCallbacks = {}; sandbox.stub(self, 'addEventListener').callsFake((eventName, cb) => { eventCallbacks[eventName] = cb; }); sandbox.spy(PrecacheController.prototype, 'install'); - sandbox.spy(PrecacheController.prototype, 'cleanup'); + sandbox.spy(PrecacheController.prototype, 'activate'); expect(PrecacheController.prototype.install.callCount).to.equal(0); @@ -64,7 +64,7 @@ describe(`[workbox-precaching] default export`, function() { eventCallbacks['activate'](installEvent); await controllerActivatePromise; - expect(PrecacheController.prototype.cleanup.callCount).to.equal(1); + expect(PrecacheController.prototype.activate.callCount).to.equal(1); }); }); diff --git a/test/workbox-precaching/node/models/test-PrecachedDetailsModel.mjs b/test/workbox-precaching/node/models/test-PrecachedDetailsModel.mjs index 8fc68d612..919ea0e03 100644 --- a/test/workbox-precaching/node/models/test-PrecachedDetailsModel.mjs +++ b/test/workbox-precaching/node/models/test-PrecachedDetailsModel.mjs @@ -1,7 +1,6 @@ import {expect} from 'chai'; import sinon from 'sinon'; import {reset as iDBReset} from 'shelving-mock-indexeddb'; -import {_private} from '../../../../packages/workbox-core/index.mjs'; import PrecachedDetailsModel from '../../../../packages/workbox-precaching/models/PrecachedDetailsModel.mjs'; import PrecacheEntry from '../../../../packages/workbox-precaching/models/PrecacheEntry.mjs'; @@ -20,16 +19,8 @@ describe('[workbox-precaching] PrecachedDetailsModel', function() { describe('constructor', function() { it(`should construct with no input`, async function() { - const model = new PrecachedDetailsModel(); - expect(model._cacheName).to.equal(`workbox-precache-/`); - }); - - it(`should construct with custom cacheName`, async function() { - const model = new PrecachedDetailsModel(`test-cache-name`); - expect(model._cacheName).to.equal(`test-cache-name`); + new PrecachedDetailsModel(); }); - - // TODO Bad cache name input }); describe('_handleUpgrade', function() { @@ -141,6 +132,7 @@ describe('[workbox-precaching] PrecachedDetailsModel', function() { it(`should return false for non-existant entry`, async function() { const model = new PrecachedDetailsModel(); const isCached = await model._isEntryCached( + 'test-cache', new PrecacheEntry( {}, '/', '1234', true ) @@ -149,6 +141,8 @@ describe('[workbox-precaching] PrecachedDetailsModel', function() { }); it(`should return false for entry with different revision`, async function() { + const cacheName = 'test-cache'; + const model = new PrecachedDetailsModel(); await model._addEntry( @@ -158,6 +152,7 @@ describe('[workbox-precaching] PrecachedDetailsModel', function() { ); const isCached = await model._isEntryCached( + cacheName, new PrecacheEntry( {}, '/', '4321', true ) @@ -166,30 +161,33 @@ describe('[workbox-precaching] PrecachedDetailsModel', function() { }); it(`should return false for entry with revision but not in cache`, async function() { + const cacheName = 'test-cache'; + const model = new PrecachedDetailsModel(); const entry = new PrecacheEntry( {}, '/', '1234', true ); await model._addEntry(entry); - const isCached = await model._isEntryCached(entry); + const isCached = await model._isEntryCached(cacheName, entry); expect(isCached).to.equal(false); }); it(`should return true if entry with revision and in cache`, async function() { + const cacheName = 'test-cache'; + const model = new PrecachedDetailsModel(); const entry = new PrecacheEntry( {}, '/', '1234', true ); - const cacheName = _private.cacheNames.getPrecacheName(); const openCache = await caches.open(cacheName); openCache.put('/', new Response('Hello')); await model._addEntry(entry); - const isCached = await model._isEntryCached(entry); + const isCached = await model._isEntryCached(cacheName, entry); expect(isCached).to.equal(true); }); }); diff --git a/test/workbox-precaching/static/precache.html b/test/workbox-precaching/static/precache.html index c15ff841b..5d842f4b7 100644 --- a/test/workbox-precaching/static/precache.html +++ b/test/workbox-precaching/static/precache.html @@ -3,9 +3,9 @@ -

precache.install() & precache.cleanup()

+

precache.install() & precache.activate()

- + diff --git a/test/workbox-range-requests/integration/range-requests-plugin.js b/test/workbox-range-requests/integration/range-requests-plugin.js index 9fda2e317..958301400 100644 --- a/test/workbox-range-requests/integration/range-requests-plugin.js +++ b/test/workbox-range-requests/integration/range-requests-plugin.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); const cleanSWEnv = require('../../../infra/testing/clean-sw'); describe(`rangeRequests.Plugin`, function() { @@ -18,7 +18,7 @@ describe(`rangeRequests.Plugin`, function() { const dummyBody = '0123456789'; await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); const partialResponseBody = await global.__workbox.webdriver.executeAsyncScript((dummyUrl, dummyBody, cb) => { const dummyResponse = new Response(dummyBody); diff --git a/test/workbox-routing/integration/navigation-route.js b/test/workbox-routing/integration/navigation-route.js index bb64ef6eb..70d351adb 100644 --- a/test/workbox-routing/integration/navigation-route.js +++ b/test/workbox-routing/integration/navigation-route.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe(`[workbox-routing] Route via NavigationRoute`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -10,7 +10,7 @@ describe(`[workbox-routing] Route via NavigationRoute`, function() { it(`should load a page and route requests`, async function() { // Load the page and wait for the first service worker to register and activate. await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); const nestedUrl = `${testingUrl}TestNavigationURL`; diff --git a/test/workbox-routing/integration/routing-basic.js b/test/workbox-routing/integration/routing-basic.js index f522a7bd7..0be2d6df7 100644 --- a/test/workbox-routing/integration/routing-basic.js +++ b/test/workbox-routing/integration/routing-basic.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe(`[workbox-routing] Basic Route`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -9,7 +9,7 @@ describe(`[workbox-routing] Basic Route`, function() { before(async function() { await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); }); it(`should honor a route created by a Route object`, async function() { diff --git a/test/workbox-routing/integration/routing-regex.js b/test/workbox-routing/integration/routing-regex.js index f830fd73c..e86d46818 100644 --- a/test/workbox-routing/integration/routing-regex.js +++ b/test/workbox-routing/integration/routing-regex.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe(`[workbox-routing] Route via RegExp`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -10,7 +10,7 @@ describe(`[workbox-routing] Route via RegExp`, function() { it(`should load a page and route requests`, async function() { // Load the page and wait for the first service worker to register and activate. await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); let testCounter = 0; diff --git a/test/workbox-strategies/integration/test-cacheFirst.js b/test/workbox-strategies/integration/test-cacheFirst.js index 29ec2f29b..f94d12bfa 100644 --- a/test/workbox-strategies/integration/test-cacheFirst.js +++ b/test/workbox-strategies/integration/test-cacheFirst.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe(`[workbox-strategies] CacheFirst Requests`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -10,7 +10,7 @@ describe(`[workbox-strategies] CacheFirst Requests`, function() { it(`should respond with cached and non-cached entry`, async function() { // Load the page and wait for the first service worker to register and activate. await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); let response = await global.__workbox.webdriver.executeAsyncScript((cb) => { fetch(new URL(`/test/workbox-strategies/static/cache-first/example.txt`, location).href) diff --git a/test/workbox-strategies/integration/test-cacheOnly.js b/test/workbox-strategies/integration/test-cacheOnly.js index dca6c564f..00034541a 100644 --- a/test/workbox-strategies/integration/test-cacheOnly.js +++ b/test/workbox-strategies/integration/test-cacheOnly.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe(`[workbox-strategies] CacheOnly Requests`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -10,7 +10,7 @@ describe(`[workbox-strategies] CacheOnly Requests`, function() { it(`should respond with cached and non-cached entry`, async function() { // Load the page and wait for the first service worker to register and activate. await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); let response = await global.__workbox.webdriver.executeAsyncScript((cb) => { fetch(new URL(`/CacheOnly/InCache/`, location).href) diff --git a/test/workbox-strategies/integration/test-networkFirst.js b/test/workbox-strategies/integration/test-networkFirst.js index 1363b826c..10f58d620 100644 --- a/test/workbox-strategies/integration/test-networkFirst.js +++ b/test/workbox-strategies/integration/test-networkFirst.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe.only(`[workbox-strategies] NetworkFirst Requests`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -50,7 +50,7 @@ describe.only(`[workbox-strategies] NetworkFirst Requests`, function() { // Load the page and wait for the first service worker to register and activate. await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); let response = await global.__workbox.webdriver.executeAsyncScript((cb) => { fetch(new URL(`/test/uniqueValue`, location).href) diff --git a/test/workbox-strategies/integration/test-networkOnly.js b/test/workbox-strategies/integration/test-networkOnly.js index d6ae9f69c..c559f1958 100644 --- a/test/workbox-strategies/integration/test-networkOnly.js +++ b/test/workbox-strategies/integration/test-networkOnly.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe.only(`[workbox-strategies] NetworkOnly Requests`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -12,7 +12,7 @@ describe.only(`[workbox-strategies] NetworkOnly Requests`, function() { // Load the page and wait for the first service worker to register and activate. await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); let response = await global.__workbox.webdriver.executeAsyncScript((cb) => { fetch(new URL(`/test/uniqueValue`, location).href) diff --git a/test/workbox-strategies/integration/test-staleWhileRevalidate.js b/test/workbox-strategies/integration/test-staleWhileRevalidate.js index bc1ad03ea..3539d56bb 100644 --- a/test/workbox-strategies/integration/test-staleWhileRevalidate.js +++ b/test/workbox-strategies/integration/test-staleWhileRevalidate.js @@ -1,6 +1,6 @@ const expect = require('chai').expect; -const activateSW = require('../../../infra/testing/activate-sw'); +const activateAndControlSW = require('../../../infra/testing/activate-and-control'); describe(`[workbox-strategies] StaleWhileRevalidate Requests`, function() { const testServerAddress = global.__workbox.server.getAddress(); @@ -50,7 +50,7 @@ describe(`[workbox-strategies] StaleWhileRevalidate Requests`, function() { // Load the page and wait for the first service worker to register and activate. await global.__workbox.webdriver.get(testingUrl); - await activateSW(swUrl); + await activateAndControlSW(swUrl); let response = await global.__workbox.webdriver.executeAsyncScript((cb) => { fetch(new URL(`/test/uniqueValue`, location).href)