c16e49e774
* fix: always-fresh service worker cache * chore: clarify service-worker * fix: cache in CacheStorage * feat: set __isDocumentCached * add back in manifest precaching * add unit tests (incomplete) * test: simplify test env * test: add service-worker cypress test * test: service-worker document handler * fix: CachedDocument ctor * fix: Readable for ReadableStream in jest * build: clean up module loading * fix: rename commands->ethereum * build: simplify package.json deps * build: clean up cypress usage * build: clean up yarn.lock * build: record cypress runs * build: disable chromeWebSecurity in cypress tests * build: rm babel * build: disable sw in ci cypress * build: nits * build: update workbox version * chore: fix merge * test: cache * test: cypress-ify the before hook * test: clear sw before each test * fix: cy then * test: cypress shenanigans * style: lint * chore: rm todo * test: fail fast for service worker with dev builds * docs: update contributing to tests * fix: clean up tests after merge - Add fast fail in case of dev server, which lacks ServiceWorker * fix: inject ethereum * test: service worker * test: increase sw timeout * test: sw state * test: run cypress in chrome * feat: add on-demand caching to improve sw startup time * test: test dynamically * fix: simplify cached doc * fix: optional sw * fix: expose response on cached doc * fix: stub out sw req * fix: intercept Co-authored-by: Christine Legge <christine.legge@uniswap.org>
85 lines
2.9 KiB
TypeScript
85 lines
2.9 KiB
TypeScript
import assert = require('assert')
|
|
|
|
describe('Service Worker', () => {
|
|
before(() => {
|
|
// Fail fast if there is no Service Worker on this build.
|
|
cy.request({ url: '/service-worker.js', headers: { 'Service-Worker': 'script' } }).then((response) => {
|
|
const isValid = isValidServiceWorker(response)
|
|
if (!isValid) {
|
|
throw new Error(
|
|
'\n' +
|
|
'Service Worker tests must be run on a production-like build\n' +
|
|
'To test, build with `yarn build:e2e` and serve with `yarn serve`'
|
|
)
|
|
}
|
|
})
|
|
|
|
function isValidServiceWorker(response: Cypress.Response<any>) {
|
|
const contentType = response.headers['content-type']
|
|
return !(response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1))
|
|
}
|
|
})
|
|
|
|
function unregister() {
|
|
return cy.log('unregister service worker').then(async () => {
|
|
const cacheKeys = await window.caches.keys()
|
|
const cacheKey = cacheKeys.find((key) => key.match(/precache/))
|
|
if (cacheKey) {
|
|
await window.caches.delete(cacheKey)
|
|
}
|
|
|
|
const sw = await window.navigator.serviceWorker.getRegistration(Cypress.config().baseUrl ?? undefined)
|
|
await sw?.unregister()
|
|
})
|
|
}
|
|
before(unregister)
|
|
after(unregister)
|
|
|
|
beforeEach(() => {
|
|
cy.intercept({ hostname: 'www.google-analytics.com' }, (req) => {
|
|
const body = req.body.toString()
|
|
if (req.query['ep.event_category'] === 'Service Worker' || body.includes('Service%20Worker')) {
|
|
if (req.query['en'] === 'Not Installed' || body.includes('Not%20Installed')) {
|
|
req.alias = 'NotInstalled'
|
|
} else if (req.query['en'] === 'Cache Hit' || body.includes('Cache%20Hit')) {
|
|
req.alias = 'CacheHit'
|
|
} else if (req.query['en'] === 'Cache Miss' || body.includes('Cache%20Miss')) {
|
|
req.alias = 'CacheMiss'
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
it('installs a ServiceWorker', () => {
|
|
cy.visit('/', { serviceWorker: true })
|
|
.get('#swap-page')
|
|
.wait('@NotInstalled', { timeout: 20000 })
|
|
.window({ timeout: 20000 })
|
|
.and((win) => {
|
|
expect(win.navigator.serviceWorker.controller?.state).to.equal('activated')
|
|
})
|
|
})
|
|
|
|
it('records a cache hit', () => {
|
|
cy.visit('/', { serviceWorker: true }).get('#swap-page').wait('@CacheHit', { timeout: 20000 })
|
|
})
|
|
|
|
it('records a cache miss', () => {
|
|
cy.then(async () => {
|
|
const cacheKeys = await window.caches.keys()
|
|
const cacheKey = cacheKeys.find((key) => key.match(/precache/))
|
|
assert(cacheKey)
|
|
|
|
const cache = await window.caches.open(cacheKey)
|
|
const keys = await cache.keys()
|
|
const key = keys.find((key) => key.url.match(/index/))
|
|
assert(key)
|
|
|
|
await cache.put(key, new Response())
|
|
})
|
|
.visit('/', { serviceWorker: true })
|
|
.get('#swap-page')
|
|
.wait('@CacheMiss', { timeout: 20000 })
|
|
})
|
|
})
|