Skip to content

Commit

Permalink
Reinitialisation scheduling (#53)
Browse files Browse the repository at this point in the history
* reinitialization scheduling

* extend test coverage

* use frozen-lockfile yarn flag for gh workflow
  • Loading branch information
walaszczykm authored Sep 5, 2022
1 parent d28c850 commit 096da2c
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 21 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-argument": "off"
"@typescript-eslint/no-unsafe-argument": "off",
"@typescript-eslint/ban-ts-comment": "off"
}
}
8 changes: 4 additions & 4 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
node-version: '16'
cache: 'yarn'
- name: Install dependecies
run: yarn
run: yarn install --frozen-lockfile
- name: Run lint script
run: yarn lint
build:
Expand All @@ -25,7 +25,7 @@ jobs:
node-version: '16'
cache: 'yarn'
- name: Install dependecies
run: yarn
run: yarn install --frozen-lockfile
- name: Run build script
run: yarn build
test:
Expand All @@ -37,7 +37,7 @@ jobs:
node-version: '16'
cache: 'yarn'
- name: Install dependecies
run: yarn
run: yarn install --frozen-lockfile
- name: Run test script
run: yarn test
e2e:
Expand All @@ -49,6 +49,6 @@ jobs:
node-version: '16'
cache: 'yarn'
- name: Install dependecies
run: yarn
run: yarn install --frozen-lockfile
- name: Start examples and run e2e tests
run: yarn e2e
34 changes: 34 additions & 0 deletions packages/widget-core/src/__tests__/create-widget.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,38 @@ describe('createWidget', () => {

expect(mockAssignCustomerData).toBeCalledWith({ name: 'foo' })
})

it('should prevent from multiple initializations', () => {
const widget: WidgetInstance = createWidget(widgetConfig)

widget.init()
widget.init()

expect(mockLiveChatWidget.init).toBeCalledTimes(1)
})

it('should prevent destroying widget while it is loading', () => {
const widget: WidgetInstance = createWidget(widgetConfig)

widget.init()
widget.destroy()

expect(mockLiveChatWidget.call).not.toBeCalledWith('destroy')
})

it('should handle `on_after_load` callback', () => {
const widget: WidgetInstance = createWidget(widgetConfig)
widget.destroy = jest.fn(widget.destroy)

widget.init()

expect(window.LC_API?.on_after_load).toBeDefined()

window.LC_API?.on_after_load?.()
expect(widget.destroy).not.toBeCalled()

widget.destroy()
window.LC_API?.on_after_load?.()
expect(widget.destroy).toBeCalledTimes(2)
})
})
10 changes: 9 additions & 1 deletion packages/widget-core/src/create-js-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import type { ExtendedWindow } from './types'

declare const window: ExtendedWindow

export function createJSApi(): void {
const scriptRef: { current: HTMLScriptElement | null } = { current: null }

export function createJSApi() {
const { slice } = Array.prototype

/* istanbul ignore next */
Expand Down Expand Up @@ -40,7 +42,13 @@ export function createJSApi(): void {
script.type = 'text/javascript'
script.src = 'https://cdn.livechatinc.com/tracking.js'
document.head.appendChild(script)
scriptRef.current = script
},
}

scriptRef.current?.remove()

window.LiveChatWidget = window.LiveChatWidget || api

return scriptRef
}
47 changes: 39 additions & 8 deletions packages/widget-core/src/create-widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,15 @@ export type WidgetInstance = {
}

type State = {
isLoading: boolean
currentEventHandlers: EventHandlers
desiredState: 'loaded' | 'destroyed' | 'unknown'
}

export function createWidget(config: WidgetConfig): WidgetInstance {
const state: State = {
isLoading: false,
desiredState: 'unknown',
currentEventHandlers: {
onReady: config.onReady,
onNewEvent: config.onNewEvent,
Expand All @@ -52,7 +56,7 @@ export function createWidget(config: WidgetConfig): WidgetInstance {
},
}

createJSApi()
const scriptRef = createJSApi()
assignConfiguration(config)
assignVisibility(config.visibility)
assignEventHandlers('on', state.currentEventHandlers)
Expand All @@ -64,31 +68,58 @@ export function createWidget(config: WidgetConfig): WidgetInstance {
window.__lc.integration_name = process.env.PACKAGE_NAME

return {
init: () => {
init() {
state.desiredState = 'loaded'
if (state.isLoading) {
return
}

window.LC_API = window.LC_API || {}
window.LC_API.on_after_load = () => {
state.isLoading = false
if (state.desiredState === 'destroyed') {
this.destroy()
}
state.desiredState = 'unknown'
}

lifecycleEmit('init')
state.isLoading = true
window.LiveChatWidget.init()
},
destroy: () => {

destroy() {
state.desiredState = 'destroyed'
if (state.isLoading) {
return
}

lifecycleEmit('destroy')
scriptRef.current?.remove()
window.LiveChatWidget.call('destroy')
},
updateVisibility: (visibility) => {

updateVisibility(visibility) {
assignVisibility(visibility)
},
updateEventHandlers: (eventHabndlers) => {

updateEventHandlers(eventHabndlers) {
assignEventHandlers('off', state.currentEventHandlers)
assignEventHandlers('on', eventHabndlers)
state.currentEventHandlers = { ...eventHabndlers }
},
updateSessionVariables: (sessionVariables) => {

updateSessionVariables(sessionVariables) {
if (sessionVariables) {
window.LiveChatWidget.call('update_session_variables', sessionVariables)
}
},
hideGreeting: () => {

hideGreeting() {
window.LiveChatWidget.call('hide_greeting')
},
updateCustomerData: (customerData) => {

updateCustomerData(customerData) {
assignCustomerData(customerData)
},
}
Expand Down
3 changes: 3 additions & 0 deletions packages/widget-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export type ExtendedWindow = Window & {
call: typeof call
init: VoidFunction
}
LC_API?: {
on_after_load?: VoidFunction
}
}

declare function on(name: 'ready', handler: EventHandlers['onReady']): void
Expand Down
8 changes: 1 addition & 7 deletions scripts/test.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import isCI from 'is-ci'

if (!fs.existsSync('packages/widget-core/dist')) {
await $`lerna run build --scope @livechat/widget-core`
}

if (isCI) {
await $`lerna run coverage`
} else {
await $`lerna run test`
}
await $`lerna run test`

0 comments on commit 096da2c

Please sign in to comment.