Merge pull request #3200 from cdr/jsjoeio/add-test-browser-register
feat(testing): add tests for registerServiceWorker
This commit is contained in:
commit
d31439ec34
|
@ -4,12 +4,12 @@ import "./pages/error.css"
|
|||
import "./pages/global.css"
|
||||
import "./pages/login.css"
|
||||
|
||||
async function registerServiceWorker(): Promise<void> {
|
||||
export async function registerServiceWorker(): Promise<void> {
|
||||
const options = getOptions()
|
||||
const path = normalize(`${options.csStaticBase}/dist/serviceWorker.js`)
|
||||
try {
|
||||
await navigator.serviceWorker.register(path, {
|
||||
scope: (options.base ?? "") + "/",
|
||||
scope: options.base + "/",
|
||||
})
|
||||
console.log("[Service Worker] registered")
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { JSDOM } from "jsdom"
|
||||
import { loggerModule } from "../utils/helpers"
|
||||
import { registerServiceWorker } from "../../src/browser/register"
|
||||
import { LocationLike } from "./util.test"
|
||||
|
||||
describe("register", () => {
|
||||
describe("when navigator and serviceWorker are defined", () => {
|
||||
|
@ -37,6 +39,12 @@ describe("register", () => {
|
|||
global.navigator = (undefined as unknown) as Navigator & typeof globalThis
|
||||
global.location = (undefined as unknown) as Location & typeof globalThis
|
||||
})
|
||||
it("test should have access to browser globals from beforeAll", () => {
|
||||
expect(typeof global.window).not.toBeFalsy()
|
||||
expect(typeof global.document).not.toBeFalsy()
|
||||
expect(typeof global.navigator).not.toBeFalsy()
|
||||
expect(typeof global.location).not.toBeFalsy()
|
||||
})
|
||||
|
||||
it("should register a ServiceWorker", () => {
|
||||
// Load service worker like you would in the browser
|
||||
|
@ -84,4 +92,89 @@ describe("register", () => {
|
|||
expect(spy).toHaveBeenCalledWith("[Service Worker] navigator is undefined")
|
||||
})
|
||||
})
|
||||
describe("registerServiceWorker", () => {
|
||||
let serviceWorkerPath: string
|
||||
let serviceWorkerScope: string
|
||||
const mockFn = jest.fn((path: string, options: { scope: string }) => {
|
||||
serviceWorkerPath = path
|
||||
serviceWorkerScope = options.scope
|
||||
return undefined
|
||||
})
|
||||
|
||||
beforeAll(() => {
|
||||
const location: LocationLike = {
|
||||
pathname: "",
|
||||
origin: "http://localhost:8080",
|
||||
}
|
||||
const { window } = new JSDOM()
|
||||
global.window = (window as unknown) as Window & typeof globalThis
|
||||
global.document = window.document
|
||||
global.navigator = window.navigator
|
||||
global.location = location as Location
|
||||
|
||||
Object.defineProperty(global.navigator, "serviceWorker", {
|
||||
value: {
|
||||
register: mockFn,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
mockFn.mockClear()
|
||||
jest.resetModules()
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
jest.restoreAllMocks()
|
||||
|
||||
// We don't want these to stay around because it can affect other tests
|
||||
global.window = (undefined as unknown) as Window & typeof globalThis
|
||||
global.document = (undefined as unknown) as Document & typeof globalThis
|
||||
global.navigator = (undefined as unknown) as Navigator & typeof globalThis
|
||||
global.location = (undefined as unknown) as Location & typeof globalThis
|
||||
})
|
||||
it("should register when options.base is undefined", async () => {
|
||||
// Mock getElementById
|
||||
const csStaticBasePath = "/static/development/Users/jp/Dev/code-server"
|
||||
const spy = jest.spyOn(document, "getElementById")
|
||||
// Create a fake element and set the attribute
|
||||
const mockElement = document.createElement("div")
|
||||
mockElement.id = "coder-options"
|
||||
mockElement.setAttribute(
|
||||
"data-settings",
|
||||
`{"csStaticBase":"${csStaticBasePath}","logLevel":2,"disableTelemetry":false,"disableUpdateCheck":false}`,
|
||||
)
|
||||
// Return mockElement from the spy
|
||||
// this way, when we call "getElementById"
|
||||
// it returns the element
|
||||
spy.mockImplementation(() => mockElement)
|
||||
|
||||
await registerServiceWorker()
|
||||
|
||||
expect(mockFn).toBeCalled()
|
||||
expect(serviceWorkerPath).toMatch(`${csStaticBasePath}/dist/serviceWorker.js`)
|
||||
expect(serviceWorkerScope).toMatch("/")
|
||||
})
|
||||
it("should register when options.base is defined", async () => {
|
||||
const csStaticBasePath = "/static/development/Users/jp/Dev/code-server"
|
||||
const spy = jest.spyOn(document, "getElementById")
|
||||
// Create a fake element and set the attribute
|
||||
const mockElement = document.createElement("div")
|
||||
mockElement.id = "coder-options"
|
||||
mockElement.setAttribute(
|
||||
"data-settings",
|
||||
`{"base":"proxy/","csStaticBase":"${csStaticBasePath}","logLevel":2,"disableTelemetry":false,"disableUpdateCheck":false}`,
|
||||
)
|
||||
// Return mockElement from the spy
|
||||
// this way, when we call "getElementById"
|
||||
// it returns the element
|
||||
spy.mockImplementation(() => mockElement)
|
||||
|
||||
await registerServiceWorker()
|
||||
|
||||
expect(mockFn).toBeCalled()
|
||||
expect(serviceWorkerPath).toMatch(`/dist/serviceWorker.js`)
|
||||
expect(serviceWorkerScope).toMatch("/")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -16,7 +16,7 @@ import { loggerModule } from "../utils/helpers"
|
|||
const dom = new JSDOM()
|
||||
global.document = dom.window.document
|
||||
|
||||
type LocationLike = Pick<Location, "pathname" | "origin">
|
||||
export type LocationLike = Pick<Location, "pathname" | "origin">
|
||||
|
||||
// jest.mock is hoisted above the imports so we must use `require` here.
|
||||
jest.mock("@coder/logger", () => require("../utils/helpers").loggerModule)
|
||||
|
|
Loading…
Reference in New Issue