openreplay/tracker/tracker-assist/tests/AnnotationCanvas.test.ts
Delirium 2ed4bba33e
feat(tracker/ui): support for multi tab sessions (#1236)
* feat(tracker): add support for multi tab sessions

* feat(backend): added support of multitabs

* fix(backend): added support of deprecated batch meta message to pre-decoder

* fix(backend): fixed nil meta issue for TabData messages in sink

* feat(player): add tabmanager

* feat(player): basic tabchange event support

* feat(player): pick tabstate for console panel and timeline

* fix(player): only display tabs that are created

* feat(player): connect performance, xray and events to tab state

* feat(player): merge all tabs data for overview

* feat(backend/tracker): extract tabdata into separate message from batchmeta

* fix(tracker): fix new session check

* fix(backend): remove batchmetadeprecated

* fix(backend): fix switch case

* fix(player): fix for tab message size

* feat(tracker): check for active tabs with broadcast channel

* feat(tracker): prevent multiple messages

* fix(tracker): ignore beacons from same tab, only ask if token isnt present yet, add small delay before start to wait for answer

* feat(player): support new msg struct in assist player

* fix(player): fix some livepl components for multi tab states

* feat(tracker): add option to disable multitab

* feat(tracker): add multitab to assist plugin

* feat(player): back compat for tab id

* fix(ui): fix missing list in controls

* fix(ui): optional list update

* feat(ui): fix visuals for multitab; use window focus event for tabs

* fix(tracker): fix for dying tests (added tabid to writer, refactored other tests)

* feat(ui): update LivePlayerSubHeader.tsx to support tabs

* feat(backend): added tabs support to devtools mob files

* feat(ui): connect state to current tab properly

* feat(backend): added multitab support to assits

* feat(backend): removed data check in agent message

* feat(backend): debug on

* fix(backend): fixed typo in message broadcast

* feat(backend): fixed issue in connect method

* fix(assist): fixed typo

* feat(assist): added more debug logs

* feat(assist): removed one log

* feat(assist): more logs

* feat(assist): use query.peerId

* feat(assist): more logs

* feat(assist): fixed session update

* fix(assist): fixed getSessions

* fix(assist): fixed request_control broadcast

* fix(assist): fixed typo

* fix(assist): added missed line

* fix(assist): fix typo

* feat(tracker): multitab support for assist sessions

* fix(tracker): fix dead tests (tabid prop)

* fix(tracker): fix yaml

* fix(tracker): timers issue

* fix(ui): fix ui E2E tests with magic?

* feat(assist): multitabs support for ee version

* fix(assist): added missed method import

* fix(tracker): fix fix events in assist

* feat(assist): added back compatibility for sessions without tabId

* fix(assist): apply message's top layer structure before broadcast call

* fix(assist): added random tabID for prev version

* fix(assist): added random tabID for prev version (ee)

* feat(assist): added debug logs

* fix(assist): fix typo in sessions_agents_count method

* fix(assist): fixed more typos in copy-pastes

* fix(tracker): fix restart timings

* feat(backend): added tabIDs for some events

* feat(ui): add tab change event to the user steps bar

* Revert "feat(backend): added tabIDs for some events"

This reverts commit 1467ad7f9f.

* feat(ui): revert timeline and xray to grab events from all tabs

* fix(ui): fix typo

---------

Co-authored-by: Alexander Zavorotynskiy <zavorotynskiy@pm.me>
2023-06-07 10:40:32 +02:00

148 lines
No EOL
5 KiB
TypeScript

import AnnotationCanvas from '../src/AnnotationCanvas'
import { describe, expect, test, it, jest, beforeEach, afterEach, } from '@jest/globals'
describe('AnnotationCanvas', () => {
let annotationCanvas
let documentBody
let canvasMock
let contextMock
beforeEach(() => {
canvasMock = {
width: 0,
height: 0,
style: {},
getContext: jest.fn(() => contextMock as unknown as HTMLCanvasElement),
parentNode: document,
}
contextMock = {
globalAlpha: 1.0,
beginPath: jest.fn(),
moveTo: jest.fn(),
lineTo: jest.fn(),
lineWidth: 8,
lineCap: 'round',
lineJoin: 'round',
strokeStyle: 'red',
stroke: jest.fn(),
globalCompositeOperation: '',
fillStyle: '',
fillRect: jest.fn(),
clearRect: jest.fn(),
}
documentBody = document.body
// @ts-ignore
document['removeChild'] = (el) => jest.fn(el)
// @ts-ignore
document['createElement'] = () => canvasMock
jest.spyOn(documentBody, 'appendChild').mockImplementation(jest.fn())
jest.spyOn(documentBody, 'removeChild').mockImplementation(jest.fn())
jest.spyOn(window, 'addEventListener').mockImplementation(jest.fn())
jest.spyOn(window, 'removeEventListener').mockImplementation(jest.fn())
annotationCanvas = new AnnotationCanvas()
})
afterEach(() => {
jest.restoreAllMocks()
})
it('should create a canvas element with correct styles when initialized', () => {
const createElSpy = jest.spyOn(document, 'createElement')
annotationCanvas = new AnnotationCanvas()
expect(createElSpy).toHaveBeenCalledWith('canvas')
expect(canvasMock.style.position).toBe('fixed')
expect(canvasMock.style.left).toBe(0)
expect(canvasMock.style.top).toBe(0)
expect(canvasMock.style.pointerEvents).toBe('none')
expect(canvasMock.style.zIndex).toBe(2147483647 - 2)
})
it('should resize the canvas when calling resizeCanvas method', () => {
annotationCanvas.resizeCanvas()
expect(canvasMock.width).toBe(window.innerWidth)
expect(canvasMock.height).toBe(window.innerHeight)
})
it('should start painting and set the last position when calling start method', () => {
const position = [10, 20,]
annotationCanvas.start(position)
expect(annotationCanvas.painting).toBe(true)
expect(annotationCanvas.clrTmID).toBeNull()
expect(annotationCanvas.lastPosition).toEqual(position)
})
it('should stop painting and call fadeOut method when calling stop method', () => {
annotationCanvas.painting = true
const fadeOutSpy = jest.spyOn(annotationCanvas, 'fadeOut')
annotationCanvas.stop()
expect(annotationCanvas.painting).toBe(false)
expect(fadeOutSpy).toHaveBeenCalled()
})
it('should not stop painting or call fadeOut method when calling stop method while not painting', () => {
annotationCanvas.painting = false
const fadeOutSpy = jest.spyOn(annotationCanvas, 'fadeOut')
annotationCanvas.stop()
expect(fadeOutSpy).not.toHaveBeenCalled()
})
it('should draw a line on the canvas when calling move method', () => {
annotationCanvas.painting = true
annotationCanvas.ctx = contextMock
const initialLastPosition = [0, 0,]
const position = [10, 20,]
annotationCanvas.move(position)
expect(contextMock.globalAlpha).toBe(1.0)
expect(contextMock.beginPath).toHaveBeenCalled()
expect(contextMock.moveTo).toHaveBeenCalledWith(initialLastPosition[0], initialLastPosition[1])
expect(contextMock.lineTo).toHaveBeenCalledWith(position[0], position[1])
expect(contextMock.stroke).toHaveBeenCalled()
expect(annotationCanvas.lastPosition).toEqual(position)
})
it('should not draw a line on the canvas when calling move method while not painting', () => {
annotationCanvas.painting = false
annotationCanvas.ctx = contextMock
const position = [10, 20,]
annotationCanvas.move(position)
expect(contextMock.beginPath).not.toHaveBeenCalled()
expect(contextMock.stroke).not.toHaveBeenCalled()
expect(annotationCanvas.lastPosition).toEqual([0, 0,])
})
it('should fade out the canvas when calling fadeOut method', () => {
annotationCanvas.ctx = contextMock
jest.useFakeTimers()
const timerSpy = jest.spyOn(window, 'setTimeout')
annotationCanvas.fadeOut()
expect(timerSpy).toHaveBeenCalledTimes(2)
expect(contextMock.globalCompositeOperation).toBe('source-over')
expect(contextMock.fillStyle).toBe('rgba(255, 255, 255, 0.1)')
expect(contextMock.fillRect).toHaveBeenCalledWith(0, 0, canvasMock.width, canvasMock.height)
jest.runOnlyPendingTimers()
expect(contextMock.clearRect).toHaveBeenCalledWith(0, 0, canvasMock.width, canvasMock.height)
})
it('should remove the canvas element when calling remove method', () => {
const spyOnRemove = jest.spyOn(document, 'removeChild')
annotationCanvas.remove()
expect(spyOnRemove).toHaveBeenCalledWith(canvasMock)
expect(window.removeEventListener).toHaveBeenCalledWith('resize', annotationCanvas.resizeCanvas)
})
})