From 48035d7f76894be763cf469ddac65d6a77521a41 Mon Sep 17 00:00:00 2001 From: Jeff Posnick Date: Wed, 22 Aug 2018 14:06:45 -0400 Subject: [PATCH 1/3] Support for offlineGoogleAnalytics: true --- .../validator/service-worker-runtime.js | 4 ++ .../options/common-generate-schema.js | 2 + .../src/entry-points/options/defaults.js | 1 + .../src/lib/populate-sw-template.js | 2 + .../lib/write-sw-using-default-template.js | 2 + .../src/templates/sw-template.js | 4 +- .../node/entry-points/generate-sw-string.js | 16 ++++++++ .../node/entry-points/generate-sw.js | 38 +++++++++++++++++++ 8 files changed, 68 insertions(+), 1 deletion(-) diff --git a/infra/testing/validator/service-worker-runtime.js b/infra/testing/validator/service-worker-runtime.js index a0153f3b2..a8f8a9e40 100644 --- a/infra/testing/validator/service-worker-runtime.js +++ b/infra/testing/validator/service-worker-runtime.js @@ -30,6 +30,9 @@ function setupSpiesAndContext() { expiration: { Plugin: CacheExpirationPlugin, }, + googleAnalytics: { + initialize: sinon.spy(), + }, precaching: { precacheAndRoute: sinon.spy(), suppressWarnings: sinon.spy(), @@ -61,6 +64,7 @@ function setupSpiesAndContext() { cacheExpirationPlugin: cacheExpirationPluginSpy, cacheFirst: workbox.strategies.cacheFirst, clientsClaim: workbox.clientsClaim, + googleAnalyticsInitialize: workbox.googleAnalytics.initialize, networkFirst: workbox.strategies.networkFirst, precacheAndRoute: workbox.precaching.precacheAndRoute, registerNavigationRoute: workbox.routing.registerNavigationRoute, diff --git a/packages/workbox-build/src/entry-points/options/common-generate-schema.js b/packages/workbox-build/src/entry-points/options/common-generate-schema.js index 3e1305e74..3afa8cc59 100644 --- a/packages/workbox-build/src/entry-points/options/common-generate-schema.js +++ b/packages/workbox-build/src/entry-points/options/common-generate-schema.js @@ -29,6 +29,8 @@ module.exports = baseSchema.keys({ navigateFallback: joi.string().default(defaults.navigateFallback), navigateFallbackBlacklist: joi.array().items(regExpObject), navigateFallbackWhitelist: joi.array().items(regExpObject), + offlineGoogleAnalytics: joi.boolean().default( + defaults.offlineGoogleAnalytics), runtimeCaching: joi.array().items(joi.object().keys({ urlPattern: [regExpObject, joi.string()], handler: [joi.func(), joi.string().valid( diff --git a/packages/workbox-build/src/entry-points/options/defaults.js b/packages/workbox-build/src/entry-points/options/defaults.js index 5b345c825..7a8bbdb03 100644 --- a/packages/workbox-build/src/entry-points/options/defaults.js +++ b/packages/workbox-build/src/entry-points/options/defaults.js @@ -24,6 +24,7 @@ module.exports = { injectionPointRegexp: /(\.precacheAndRoute\()\s*\[\s*\]\s*(\)|,)/, maximumFileSizeToCacheInBytes: 2 * 1024 * 1024, navigateFallback: undefined, + offlineGoogleAnalytics: false, purgeOnQuotaError: false, skipWaiting: false, }; diff --git a/packages/workbox-build/src/lib/populate-sw-template.js b/packages/workbox-build/src/lib/populate-sw-template.js index 3dbf4f550..19aa51031 100644 --- a/packages/workbox-build/src/lib/populate-sw-template.js +++ b/packages/workbox-build/src/lib/populate-sw-template.js @@ -31,6 +31,7 @@ module.exports = ({ navigateFallback, navigateFallbackBlacklist, navigateFallbackWhitelist, + offlineGoogleAnalytics, runtimeCaching, skipWaiting, workboxSWImport, @@ -64,6 +65,7 @@ module.exports = ({ navigateFallback, navigateFallbackBlacklist, navigateFallbackWhitelist, + offlineGoogleAnalytics, precacheOptionsString, skipWaiting, runtimeCaching: runtimeCachingConverter(runtimeCaching), diff --git a/packages/workbox-build/src/lib/write-sw-using-default-template.js b/packages/workbox-build/src/lib/write-sw-using-default-template.js index 095152464..4a573775b 100644 --- a/packages/workbox-build/src/lib/write-sw-using-default-template.js +++ b/packages/workbox-build/src/lib/write-sw-using-default-template.js @@ -32,6 +32,7 @@ module.exports = async ({ navigateFallback, navigateFallbackBlacklist, navigateFallbackWhitelist, + offlineGoogleAnalytics, runtimeCaching, skipWaiting, swDest, @@ -56,6 +57,7 @@ module.exports = async ({ navigateFallback, navigateFallbackBlacklist, navigateFallbackWhitelist, + offlineGoogleAnalytics, runtimeCaching, skipWaiting, workboxSWImport, diff --git a/packages/workbox-build/src/templates/sw-template.js b/packages/workbox-build/src/templates/sw-template.js index 3172f9e93..75ea55ed6 100644 --- a/packages/workbox-build/src/templates/sw-template.js +++ b/packages/workbox-build/src/templates/sw-template.js @@ -62,4 +62,6 @@ if (Array.isArray(self.__precacheManifest)) { <% if (navigateFallbackBlacklist) { %>blacklist: [<%= navigateFallbackBlacklist %>],<% } %> }<% } %>);<% } %> -<% if (runtimeCaching) { runtimeCaching.forEach(runtimeCachingString => {%><%= runtimeCachingString %><% });} %>`; +<% if (runtimeCaching) { runtimeCaching.forEach(runtimeCachingString => {%><%= runtimeCachingString %><% });} %> + +<% if (offlineGoogleAnalytics) { %>workbox.googleAnalytics.initialize();<% } %>`; diff --git a/test/workbox-build/node/entry-points/generate-sw-string.js b/test/workbox-build/node/entry-points/generate-sw-string.js index 1fdd5900a..0671ece1d 100644 --- a/test/workbox-build/node/entry-points/generate-sw-string.js +++ b/test/workbox-build/node/entry-points/generate-sw-string.js @@ -30,6 +30,7 @@ describe(`[workbox-build] entry-points/generate-sw-string.js (End to End)`, func 'modifyUrlPrefix', 'navigateFallback', 'navigateFallbackWhitelist', + 'offlineGoogleAnalytics', 'runtimeCaching', 'skipWaiting', 'templatedUrls', @@ -231,6 +232,21 @@ describe(`[workbox-build] entry-points/generate-sw-string.js (End to End)`, func }]], }}); }); + + it(`should use defaults when all the required parameters are present, with 'offlineGoogleAnalytics'`, async function() { + const options = Object.assign({}, BASE_OPTIONS, { + offlineGoogleAnalytics: true, + }); + + const {swString, warnings} = await generateSWString(options); + expect(warnings).to.be.empty; + await validateServiceWorkerRuntime({swString, expectedMethodCalls: { + importScripts: [[...DEFAULT_IMPORT_SCRIPTS]], + suppressWarnings: [[]], + precacheAndRoute: [[[], {}]], + googleAnalyticsInitialize: [[]], + }}); + }); }); describe(`[workbox-build] behavior with 'runtimeCaching'`, function() { diff --git a/test/workbox-build/node/entry-points/generate-sw.js b/test/workbox-build/node/entry-points/generate-sw.js index f97228b9a..9c0440c97 100644 --- a/test/workbox-build/node/entry-points/generate-sw.js +++ b/test/workbox-build/node/entry-points/generate-sw.js @@ -37,6 +37,7 @@ describe(`[workbox-build] entry-points/generate-sw.js (End to End)`, function() 'manifestTransforms', 'maximumFileSizeToCacheInBytes', 'modifyUrlPrefix', + 'offlineGoogleAnalytics', 'navigateFallback', 'navigateFallbackWhitelist', 'runtimeCaching', @@ -462,6 +463,43 @@ describe(`[workbox-build] entry-points/generate-sw.js (End to End)`, function() }], {}]], }}); }); + + it(`should use defaults when all the required parameters are present, with 'offlineGoogleAnalytics'`, async function() { + const swDest = tempy.file(); + const options = Object.assign({}, BASE_OPTIONS, { + swDest, + offlineGoogleAnalytics: true, + }); + + const {count, size, warnings} = await generateSW(options); + expect(warnings).to.be.empty; + expect(count).to.eql(6); + expect(size).to.eql(2421); + await validateServiceWorkerRuntime({swFile: swDest, expectedMethodCalls: { + importScripts: [[WORKBOX_SW_CDN_URL]], + suppressWarnings: [[]], + precacheAndRoute: [[[{ + url: 'index.html', + revision: '3883c45b119c9d7e9ad75a1b4a4672ac', + }, { + url: 'page-1.html', + revision: '544658ab25ee8762dc241e8b1c5ed96d', + }, { + url: 'page-2.html', + revision: 'a3a71ce0b9b43c459cf58bd37e911b74', + }, { + url: 'styles/stylesheet-1.css', + revision: '934823cbc67ccf0d67aa2a2eeb798f12', + }, { + url: 'styles/stylesheet-2.css', + revision: '884f6853a4fc655e4c2dc0c0f27a227c', + }, { + url: 'webpackEntry.js', + revision: 'd41d8cd98f00b204e9800998ecf8427e', + }], {}]], + googleAnalyticsInitialize: [[]], + }}); + }); }); describe(`[workbox-build] behavior with 'runtimeCaching'`, function() { From e5a14cbf75b95c9501e2c307ab1d207b6c112f4a Mon Sep 17 00:00:00 2001 From: Jeff Posnick Date: Wed, 22 Aug 2018 14:23:13 -0400 Subject: [PATCH 2/3] Fixing a test. --- test/workbox-build/node/lib/populate-sw-template.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/workbox-build/node/lib/populate-sw-template.js b/test/workbox-build/node/lib/populate-sw-template.js index e8e9a9367..15f07e9c2 100644 --- a/test/workbox-build/node/lib/populate-sw-template.js +++ b/test/workbox-build/node/lib/populate-sw-template.js @@ -47,6 +47,7 @@ describe(`[workbox-build] lib/populate-sw-template.js`, function() { navigateFallback: undefined, navigateFallbackBlacklist: undefined, navigateFallbackWhitelist: undefined, + offlineGoogleAnalytics: undefined, precacheOptionsString, runtimeCaching: runtimeCachingPlaceholder, skipWaiting: undefined, @@ -66,6 +67,7 @@ describe(`[workbox-build] lib/populate-sw-template.js`, function() { const navigateFallback = '/shell.html'; const navigateFallbackBlacklist = [/another-test/]; const navigateFallbackWhitelist = [/test/]; + const offlineGoogleAnalytics = true; const runtimeCaching = []; const runtimeCachingPlaceholder = 'runtime-caching-placeholder'; const skipWaiting = true; @@ -97,6 +99,7 @@ describe(`[workbox-build] lib/populate-sw-template.js`, function() { navigateFallback, navigateFallbackBlacklist, navigateFallbackWhitelist, + offlineGoogleAnalytics, runtimeCaching, skipWaiting, workboxSWImport, @@ -112,6 +115,7 @@ describe(`[workbox-build] lib/populate-sw-template.js`, function() { navigateFallback, navigateFallbackBlacklist, navigateFallbackWhitelist, + offlineGoogleAnalytics, runtimeCaching: runtimeCachingPlaceholder, precacheOptionsString, skipWaiting, From f4f9a5b79e4b3010451fdc25c6a610b341ba658c Mon Sep 17 00:00:00 2001 From: Jeff Posnick Date: Wed, 22 Aug 2018 15:37:34 -0400 Subject: [PATCH 3/3] Support for complex config. --- .../options/common-generate-schema.js | 4 +- .../src/lib/populate-sw-template.js | 15 +++++- .../src/lib/runtime-caching-converter.js | 14 ++---- .../src/lib/stringify-without-comments.js | 24 +++++++++ .../src/templates/sw-template.js | 2 +- .../node/entry-points/generate-sw-string.js | 27 +++++++++- .../node/entry-points/generate-sw.js | 49 ++++++++++++++++++- .../node/lib/populate-sw-template.js | 48 +++++++++++++++++- 8 files changed, 163 insertions(+), 20 deletions(-) create mode 100644 packages/workbox-build/src/lib/stringify-without-comments.js diff --git a/packages/workbox-build/src/entry-points/options/common-generate-schema.js b/packages/workbox-build/src/entry-points/options/common-generate-schema.js index 3afa8cc59..81b819520 100644 --- a/packages/workbox-build/src/entry-points/options/common-generate-schema.js +++ b/packages/workbox-build/src/entry-points/options/common-generate-schema.js @@ -29,8 +29,8 @@ module.exports = baseSchema.keys({ navigateFallback: joi.string().default(defaults.navigateFallback), navigateFallbackBlacklist: joi.array().items(regExpObject), navigateFallbackWhitelist: joi.array().items(regExpObject), - offlineGoogleAnalytics: joi.boolean().default( - defaults.offlineGoogleAnalytics), + offlineGoogleAnalytics: joi.alternatives().try(joi.boolean(), joi.object()) + .default(defaults.offlineGoogleAnalytics), runtimeCaching: joi.array().items(joi.object().keys({ urlPattern: [regExpObject, joi.string()], handler: [joi.func(), joi.string().valid( diff --git a/packages/workbox-build/src/lib/populate-sw-template.js b/packages/workbox-build/src/lib/populate-sw-template.js index 19aa51031..ff3baae43 100644 --- a/packages/workbox-build/src/lib/populate-sw-template.js +++ b/packages/workbox-build/src/lib/populate-sw-template.js @@ -19,6 +19,7 @@ const swTemplate = require('../templates/sw-template'); const errors = require('./errors'); const runtimeCachingConverter = require('./runtime-caching-converter'); +const stringifyWithoutComments = require('./stringify-without-comments'); module.exports = ({ cacheId, @@ -55,6 +56,18 @@ module.exports = ({ ); } + let offlineAnalyticsConfigString; + if (offlineGoogleAnalytics) { + // If offlineGoogleAnalytics is a truthy value, we need to convert it to the + // format expected by the template. + offlineAnalyticsConfigString = offlineGoogleAnalytics === true ? + // If it's the literal value true, then use an empty config string. + '{}' : + // Otherwise, convert the config object into a more complex string, taking + // into account the fact that functions might need to be stringified. + stringifyWithoutComments(offlineGoogleAnalytics); + } + try { const populatedTemplate = template(swTemplate)({ cacheId, @@ -65,7 +78,7 @@ module.exports = ({ navigateFallback, navigateFallbackBlacklist, navigateFallbackWhitelist, - offlineGoogleAnalytics, + offlineAnalyticsConfigString, precacheOptionsString, skipWaiting, runtimeCaching: runtimeCachingConverter(runtimeCaching), diff --git a/packages/workbox-build/src/lib/runtime-caching-converter.js b/packages/workbox-build/src/lib/runtime-caching-converter.js index 17292a783..7082379ee 100644 --- a/packages/workbox-build/src/lib/runtime-caching-converter.js +++ b/packages/workbox-build/src/lib/runtime-caching-converter.js @@ -15,10 +15,9 @@ */ const ol = require('common-tags').oneLine; -const objectStringify = require('stringify-object'); -const stripComments = require('strip-comments'); -const errors = require('./errors'); +const errors = require('./errors'); +const stringifyWithoutComments = require('./stringify-without-comments'); /** * Given a set of options that configures `sw-toolbox`'s behavior, convert it @@ -33,13 +32,8 @@ const errors = require('./errors'); function getOptionsString(options = {}) { let plugins = []; if (options.plugins) { - // Using libs because JSON.stringify won't handle functions - plugins = options.plugins.map((plugin) => - objectStringify(plugin, { - transform: (_obj, _prop, str) => stripComments(str), - }) - ); - + // Using libs because JSON.stringify won't handle functions. + plugins = options.plugins.map(stringifyWithoutComments); delete options.plugins; } diff --git a/packages/workbox-build/src/lib/stringify-without-comments.js b/packages/workbox-build/src/lib/stringify-without-comments.js new file mode 100644 index 000000000..8429ff7d2 --- /dev/null +++ b/packages/workbox-build/src/lib/stringify-without-comments.js @@ -0,0 +1,24 @@ +/* + Copyright 2018 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const objectStringify = require('stringify-object'); +const stripComments = require('strip-comments'); + +module.exports = (obj) => { + return objectStringify(obj, { + transform: (_obj, _prop, str) => stripComments(str), + }); +}; diff --git a/packages/workbox-build/src/templates/sw-template.js b/packages/workbox-build/src/templates/sw-template.js index 75ea55ed6..d34dfc876 100644 --- a/packages/workbox-build/src/templates/sw-template.js +++ b/packages/workbox-build/src/templates/sw-template.js @@ -64,4 +64,4 @@ if (Array.isArray(self.__precacheManifest)) { <% if (runtimeCaching) { runtimeCaching.forEach(runtimeCachingString => {%><%= runtimeCachingString %><% });} %> -<% if (offlineGoogleAnalytics) { %>workbox.googleAnalytics.initialize();<% } %>`; +<% if (offlineAnalyticsConfigString) { %>workbox.googleAnalytics.initialize(<%= offlineAnalyticsConfigString %>);<% } %>`; diff --git a/test/workbox-build/node/entry-points/generate-sw-string.js b/test/workbox-build/node/entry-points/generate-sw-string.js index 0671ece1d..7ebd19c5a 100644 --- a/test/workbox-build/node/entry-points/generate-sw-string.js +++ b/test/workbox-build/node/entry-points/generate-sw-string.js @@ -233,7 +233,7 @@ describe(`[workbox-build] entry-points/generate-sw-string.js (End to End)`, func }}); }); - it(`should use defaults when all the required parameters are present, with 'offlineGoogleAnalytics'`, async function() { + it(`should use defaults when all the required parameters are present, with 'offlineGoogleAnalytics' set to true`, async function() { const options = Object.assign({}, BASE_OPTIONS, { offlineGoogleAnalytics: true, }); @@ -244,7 +244,30 @@ describe(`[workbox-build] entry-points/generate-sw-string.js (End to End)`, func importScripts: [[...DEFAULT_IMPORT_SCRIPTS]], suppressWarnings: [[]], precacheAndRoute: [[[], {}]], - googleAnalyticsInitialize: [[]], + googleAnalyticsInitialize: [[{}]], + }}); + }); + + it(`should use defaults when all the required parameters are present, with 'offlineGoogleAnalytics' set to a config`, async function() { + const options = Object.assign({}, BASE_OPTIONS, { + offlineGoogleAnalytics: { + parameterOverrides: { + cd1: 'offline', + }, + }, + }); + + const {swString, warnings} = await generateSWString(options); + expect(warnings).to.be.empty; + await validateServiceWorkerRuntime({swString, expectedMethodCalls: { + importScripts: [[...DEFAULT_IMPORT_SCRIPTS]], + suppressWarnings: [[]], + precacheAndRoute: [[[], {}]], + googleAnalyticsInitialize: [[{ + parameterOverrides: { + cd1: 'offline', + }, + }]], }}); }); }); diff --git a/test/workbox-build/node/entry-points/generate-sw.js b/test/workbox-build/node/entry-points/generate-sw.js index 9c0440c97..d76b21bf0 100644 --- a/test/workbox-build/node/entry-points/generate-sw.js +++ b/test/workbox-build/node/entry-points/generate-sw.js @@ -464,7 +464,7 @@ describe(`[workbox-build] entry-points/generate-sw.js (End to End)`, function() }}); }); - it(`should use defaults when all the required parameters are present, with 'offlineGoogleAnalytics'`, async function() { + it(`should use defaults when all the required parameters are present, with 'offlineGoogleAnalytics' set to true`, async function() { const swDest = tempy.file(); const options = Object.assign({}, BASE_OPTIONS, { swDest, @@ -497,7 +497,52 @@ describe(`[workbox-build] entry-points/generate-sw.js (End to End)`, function() url: 'webpackEntry.js', revision: 'd41d8cd98f00b204e9800998ecf8427e', }], {}]], - googleAnalyticsInitialize: [[]], + googleAnalyticsInitialize: [[{}]], + }}); + }); + + it(`should use defaults when all the required parameters are present, with 'offlineGoogleAnalytics' set to a config`, async function() { + const swDest = tempy.file(); + const options = Object.assign({}, BASE_OPTIONS, { + swDest, + offlineGoogleAnalytics: { + parameterOverrides: { + cd1: 'offline', + }, + }, + }); + + const {count, size, warnings} = await generateSW(options); + expect(warnings).to.be.empty; + expect(count).to.eql(6); + expect(size).to.eql(2421); + await validateServiceWorkerRuntime({swFile: swDest, expectedMethodCalls: { + importScripts: [[WORKBOX_SW_CDN_URL]], + suppressWarnings: [[]], + precacheAndRoute: [[[{ + url: 'index.html', + revision: '3883c45b119c9d7e9ad75a1b4a4672ac', + }, { + url: 'page-1.html', + revision: '544658ab25ee8762dc241e8b1c5ed96d', + }, { + url: 'page-2.html', + revision: 'a3a71ce0b9b43c459cf58bd37e911b74', + }, { + url: 'styles/stylesheet-1.css', + revision: '934823cbc67ccf0d67aa2a2eeb798f12', + }, { + url: 'styles/stylesheet-2.css', + revision: '884f6853a4fc655e4c2dc0c0f27a227c', + }, { + url: 'webpackEntry.js', + revision: 'd41d8cd98f00b204e9800998ecf8427e', + }], {}]], + googleAnalyticsInitialize: [[{ + parameterOverrides: { + cd1: 'offline', + }, + }]], }}); }); }); diff --git a/test/workbox-build/node/lib/populate-sw-template.js b/test/workbox-build/node/lib/populate-sw-template.js index 15f07e9c2..ba89cf728 100644 --- a/test/workbox-build/node/lib/populate-sw-template.js +++ b/test/workbox-build/node/lib/populate-sw-template.js @@ -47,7 +47,7 @@ describe(`[workbox-build] lib/populate-sw-template.js`, function() { navigateFallback: undefined, navigateFallbackBlacklist: undefined, navigateFallbackWhitelist: undefined, - offlineGoogleAnalytics: undefined, + offlineAnalyticsConfigString: undefined, precacheOptionsString, runtimeCaching: runtimeCachingPlaceholder, skipWaiting: undefined, @@ -68,6 +68,7 @@ describe(`[workbox-build] lib/populate-sw-template.js`, function() { const navigateFallbackBlacklist = [/another-test/]; const navigateFallbackWhitelist = [/test/]; const offlineGoogleAnalytics = true; + const offlineAnalyticsConfigString = '{}'; const runtimeCaching = []; const runtimeCachingPlaceholder = 'runtime-caching-placeholder'; const skipWaiting = true; @@ -115,11 +116,54 @@ describe(`[workbox-build] lib/populate-sw-template.js`, function() { navigateFallback, navigateFallbackBlacklist, navigateFallbackWhitelist, - offlineGoogleAnalytics, + offlineAnalyticsConfigString, runtimeCaching: runtimeCachingPlaceholder, precacheOptionsString, skipWaiting, workboxSWImport, }]); }); + + it(`should handle a complex offlineGoogleAnalytics value when populating the template`, function() { + const runtimeCachingPlaceholder = 'runtime-caching-placeholder'; + const swTemplate = 'template'; + const precacheOptionsString = '{}'; + const offlineGoogleAnalytics = { + parameterOverrides: { + cd1: 'offline', + }, + hitFilter: (params) => { + // Comments are stripped. + params.set('cm1', params.get('qt')); + }, + }; + const offlineAnalyticsConfigString = `{\n\tparameterOverrides: {\n\t\tcd1: 'offline'\n\t},\n\thitFilter: (params) => {\n \n params.set('cm1', params.get('qt'));\n }\n}`; + + const innerStub = sinon.stub().returns(''); + const outerStub = sinon.stub().returns(innerStub); + const populateSWTemplate = proxyquire(MODULE_PATH, { + 'lodash.template': outerStub, + './runtime-caching-converter': () => runtimeCachingPlaceholder, + '../templates/sw-template': swTemplate, + }); + + populateSWTemplate({offlineGoogleAnalytics}); + + expect(outerStub.alwaysCalledWith(swTemplate)).to.be.true; + expect(innerStub.args[0]).to.eql([{ + cacheId: undefined, + clientsClaim: undefined, + importScripts: undefined, + manifestEntries: undefined, + modulePathPrefix: undefined, + navigateFallback: undefined, + navigateFallbackBlacklist: undefined, + navigateFallbackWhitelist: undefined, + offlineAnalyticsConfigString, + precacheOptionsString, + runtimeCaching: runtimeCachingPlaceholder, + skipWaiting: undefined, + workboxSWImport: undefined, + }]); + }); });