Skip to content

Commit

Permalink
test: update unit tests for service layer (checkly#170)
Browse files Browse the repository at this point in the history
* test: new tests for constants, selector and analytics services

* refactor: add jest mocks and change wording

* test: test for badge service (start/pause)

* test: reset text test for badge service

* test: stop recording test for badge service

* refactor: create a describe for each function

* feat: add storage basic test case

* feat: add storage remove and set test case

* feat: add storage complete test

* feat: complete browser tests

* refactor: remove jest-chrome dep

* refactor: remove selector test that wasnt working

Co-authored-by: Pilar Checkly <[email protected]>
Co-authored-by: Ignacio Anaya <[email protected]>
Co-authored-by: Pilar Checkly <[email protected]>
Co-authored-by: Pilar Checkly <[email protected]>
Co-authored-by: Pilar Checkly <[email protected]>
  • Loading branch information
6 people authored Oct 19, 2021
1 parent 4326660 commit 176278e
Show file tree
Hide file tree
Showing 11 changed files with 1,298 additions and 838 deletions.
2 changes: 2 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module.exports = {
preset: '@vue/cli-plugin-unit-jest',
transform: {
'^.+\\.vue$': 'vue-jest',
"^.+\\.js$": "babel-jest",
},
setupFilesAfterEnv: ['./jest.setup.js'],
moduleFileExtensions: ["js", "json", "vue"],
}
1,774 changes: 941 additions & 833 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@
"@vue/compiler-sfc": "3.0.0",
"@vue/eslint-config-prettier": "6.0.0",
"@vue/test-utils": "2.0.0-rc.6",
"@vue/vue3-jest": "27.0.0-alpha.1",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "10.1.0",
"eslint": "6.7.2",
"eslint-plugin-prettier": "3.1.3",
"eslint-plugin-vue": "7.0.0",
"eslint-plugin-vuejs-accessibility": "0.6.2",
"jest": "26.6.3",
"jest": "27.2.5",
"jest-vue-preprocessor": "1.7.1",
"node-sass": "5.0.0",
"playwright": "1.10.0",
Expand All @@ -49,6 +51,6 @@
"typescript": "3.9.3",
"vue-cli-plugin-browser-extension": "0.25.1",
"vue-cli-plugin-tailwind": "2.0.6",
"vue-jest": "^5.0.0-0"
"vue-jest": "3.0.7"
}
}
36 changes: 36 additions & 0 deletions src/services/__tests__/analytics.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import analytics from '../analytics'

Object.defineProperty(window, '_gaq', {
writable: true,
value: {
push: jest.fn(),
},
})

describe('trackPageView', () => {
beforeEach(() => {
window._gaq.push.mockClear()
})

it('has telemetry enabled', () => {
const options = {
extension: {
telemetry: true,
},
}

analytics.trackPageView(options)
expect(window._gaq.push.mock.calls.length).toBe(1)
})

it('does not have telemetry enabled', () => {
const options = {
extension: {
telemetry: false,
},
}

analytics.trackPageView(options)
expect(window._gaq.push.mock.calls.length).toBe(0)
})
})
65 changes: 65 additions & 0 deletions src/services/__tests__/badge.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import badge from '../badge'

global.chrome = {
browserAction: {
setIcon: jest.fn(),
setBadgeText: jest.fn(text => (inputText.data = text)),
setBadgeBackgroundColor: jest.fn(),
},
}

const inputText = {
data: '',
}

beforeEach(() => {
chrome.browserAction.setIcon.mockClear()
chrome.browserAction.setBadgeBackgroundColor.mockClear()
})

describe('start', () => {
it('sets recording icon', () => {
badge.start()
expect(chrome.browserAction.setIcon.mock.calls.length).toBe(1)
})
})

describe('pause', () => {
it('sets pause icon', () => {
badge.pause()
expect(chrome.browserAction.setIcon.mock.calls.length).toBe(1)
})
})

describe('setText', () => {
it('sets selected text on the badge', () => {
badge.setText('data')
expect(inputText.data.text).toBe('data')
})
})

describe('reset', () => {
it('reset text to empty string', () => {
badge.reset()
badge.setText('')
expect(inputText.data.text).toBe('')
})
})

describe('wait', () => {
it('changes text to wait', () => {
badge.wait()
badge.setText('wait')
expect(chrome.browserAction.setBadgeBackgroundColor.mock.calls.length).toBe(1)
expect(inputText.data.text).toBe('wait')
})
})

describe('stop', () => {
it('stops recording and sets result text', () => {
badge.stop('data')
expect(chrome.browserAction.setIcon.mock.calls.length).toBe(1)
expect(chrome.browserAction.setBadgeBackgroundColor.mock.calls.length).toBe(1)
expect(inputText.data.text).toBe('data')
})
})
112 changes: 112 additions & 0 deletions src/services/__tests__/browser.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import browser from '../browser'

const activeTab = { id: 1, active: true }

const copyText = {
data: '',
}

const cookies = [
{
name: 'checkly'
}
]


window.chrome = {
tabs: {
create: jest.fn(),
query: jest.fn((options, cb) => (cb([activeTab]))),
executeScript: jest.fn((options, cb) => (cb(options))),
sendMessage: jest.fn(),
},
extension: {
connect: jest.fn(),
},
runtime: {
openOptionsPage: jest.fn()
},
cookies: {
getAll: jest.fn((options, cb) => (cb(cookies)))
}}

global.navigator.permissions = {
query: jest
.fn()
.mockImplementationOnce(() => Promise.resolve({ state: 'granted' })),
};

global.navigator.clipboard = {
writeText: jest.fn(text => (copyText.data = text))
};

beforeEach(() => {
window?.chrome?.tabs.create.mockClear()
window?.chrome?.extension.connect.mockClear()
window?.chrome?.runtime.openOptionsPage.mockClear()
window?.chrome?.tabs.query.mockClear()
})

describe('getActiveTab', () => {
it('returns the active tab', async () => {
const activeTab = await browser.getActiveTab()
expect(activeTab).toBe(activeTab)
expect(window.chrome.tabs.query.mock.calls.length).toBe(1)
})
})

describe('copyToClipboard', () => {
it('copies text to clipboard', async () => {
await browser.copyToClipboard('data')
expect(window.navigator.clipboard.writeText.mock.calls.length).toBe(1)
})
})

describe('injectContentScript', () => {
it('executes content script', async () => {
await browser.injectContentScript()
expect(window.chrome.tabs.executeScript.mock.calls.length).toBe(1)
})
})

describe('getChecklyCookie', () => {
it('returns checkly cookie', async () => {
await browser.getChecklyCookie()
expect(window.chrome.cookies.getAll.mock.calls.length).toBe(1)
})
})

describe('openChecklyRunner', () => {
it('is not logged in', () => {
browser.openChecklyRunner({code: 1, runner: 2, isLoggedIn: false})
expect(window.chrome.tabs.create.mock.calls.length).toBe(1)
})

it('is logged in', () => {
browser.openChecklyRunner({code: 1, runner: 2, isLoggedIn: true})
expect(window.chrome.tabs.create.mock.calls.length).toBe(1)
})
})

describe('getBackgroundBus', () => {
it('gets backgorund bus', async () => {
browser.getBackgroundBus()
expect(window.chrome.extension.connect.mock.calls.length).toBe(1)
})
})

describe('openOptionsPage', () => {
it('calls function that opens options page', async () => {
browser.openOptionsPage()
expect(window.chrome.runtime.openOptionsPage.mock.calls.length).toBe(1)
})
})

describe('openHelpPage', () => {
it('calls function that creates new tab and opens help page', async () => {
browser.openHelpPage()
expect(window.chrome.tabs.create.mock.calls.length).toBe(1)
})
})


29 changes: 29 additions & 0 deletions src/services/__tests__/constants.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { isDarkMode } from '../constants'

function setMatchMediaMock(matches) {
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn(() => ({ matches })),
})
}

describe('isDarkMode()', () => {
beforeEach(() => {
window?.matchMedia?.mockClear()
})

it('has darkMode enabled', () => {
setMatchMediaMock(true)
expect(isDarkMode()).toBe(true)
})

it('has darkMode disabled', () => {
setMatchMediaMock(false)
expect(isDarkMode()).toBe(false)
})

it('does not have matchMedia browser API', () => {
window.matchMedia = null
expect(isDarkMode()).toBe(false)
})
})
105 changes: 105 additions & 0 deletions src/services/__tests__/storage.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import storage from '../storage'

const store = {
token: 'xxx',
name: 'lionel',
}

beforeEach(() => {
window.chrome = {
storage: {
local: {
get: jest.fn((keys, cb) => {
if (typeof keys === 'string') {
return cb(store[keys])
}

const results = []
if (Array.isArray(keys)) {
keys.forEach(key => {
results.push(store[key])
})

return cb(results)
}
}),
remove: jest.fn((keys, cb) => {
delete store[keys];
return cb(store)
}),
set: jest.fn((props, cb) => {
const newStore = { ...store, ...props }
return cb(newStore)
}),
},
},
}

window.chrome.storage.local.get.mockClear()
window.chrome.storage.local.set.mockClear()
window.chrome.storage.local.remove.mockClear()
})

describe('get', () => {
it('return a single value', async () => {
const token = await storage.get('token')
expect(token).toBe(store.token)
expect(window.chrome.storage.local.get.mock.calls.length).toBe(1)
})

it('return multiple values', async () => {
const [token, name] = await storage.get(['token', 'name'])
expect(token).toBe(store.token)
expect(name).toBe(store.name)
expect(window.chrome.storage.local.get.mock.calls.length).toBe(1)
})

it('return undefined when value not found', async () => {
const nothing = await storage.get('nothing')
expect(nothing).toBe(undefined)
})

it('does not have browser storage available', async () => {
try {
window.chrome.storage = null
await storage.get('token');
} catch (e) {
expect(e).toEqual('Browser storage not available');
}
})
})

describe('remove', () => {
it('removes a value', async () => {
const store = await storage.remove('token')
expect(store.token).toBe(undefined)
expect(window.chrome.storage.local.remove.mock.calls.length).toBe(1)
})

it('does not have browser storage available', async () => {
try {
window.chrome.storage = null
await storage.remove('token');
} catch (e) {
expect(e).toEqual('Browser storage not available');
}
})
})

describe('set', () => {
it('set a new value or values', async () => {
const newStore = await storage.set({age: 1, country: 2})
expect(newStore.age).toBe(1)
expect(newStore.country).toBe(2)
expect(window.chrome.storage.local.set.mock.calls.length).toBe(1)
})

it('does not have browser storage available', async () => {
try {
window.chrome.storage = null
await storage.set({age: 1, country: 2});
} catch (e) {
expect(e).toEqual('Browser storage not available');
}
})
})
3 changes: 2 additions & 1 deletion src/services/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export default {
},

copyToClipboard(text) {
return navigator.permissions.query({ name: 'clipboard-write' }).then(result => {
return navigator.permissions.query({ name: 'clipboard-write' })
.then(result => {
if (result.state !== 'granted' && result.state !== 'prompt') {
return Promise.reject()
}
Expand Down
Loading

0 comments on commit 176278e

Please sign in to comment.