change(ui): squash~ add unit tests and visual testing for replayer and session class
This commit is contained in:
parent
9b9e268c1f
commit
e346541411
24 changed files with 13272 additions and 23 deletions
3
frontend/.gitignore
vendored
3
frontend/.gitignore
vendored
|
|
@ -15,3 +15,6 @@ app/components/ui/SVG.js
|
|||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
*.env.json
|
||||
cypress.env.json
|
||||
cypress/snapshots/__diff_output__/
|
||||
|
|
@ -67,9 +67,13 @@ function WebPlayer(props: any) {
|
|||
}
|
||||
|
||||
const jumpToTime = props.query.get('jumpto');
|
||||
const freeze = props.query.get('freeze')
|
||||
if (jumpToTime) {
|
||||
WebPlayerInst.jump(parseInt(jumpToTime));
|
||||
}
|
||||
if (freeze) {
|
||||
WebPlayerInst.freeze()
|
||||
}
|
||||
|
||||
return () => WebPlayerInst.clean();
|
||||
}, [session.sessionId]);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ export interface SetState {
|
|||
completed: boolean
|
||||
live: boolean
|
||||
livePlay: boolean
|
||||
freeze: boolean
|
||||
|
||||
endTime: number
|
||||
}
|
||||
|
|
@ -46,6 +47,7 @@ export default class Animator {
|
|||
completed: false,
|
||||
live: false,
|
||||
livePlay: false,
|
||||
freeze: false,
|
||||
|
||||
endTime: 0,
|
||||
} as const
|
||||
|
|
@ -129,6 +131,7 @@ export default class Animator {
|
|||
}
|
||||
|
||||
play() {
|
||||
if (this.store.get().freeze) return;
|
||||
if (!this.store.get().ready) {
|
||||
cancelAnimationFrame(this.animationFrameRequestId)
|
||||
this.store.update({ playing: true })
|
||||
|
|
@ -145,6 +148,18 @@ export default class Animator {
|
|||
this.store.update({ playing: false })
|
||||
}
|
||||
|
||||
freeze() {
|
||||
if (this.store.get().ready) {
|
||||
// making sure that replay is displayed completely
|
||||
setTimeout(() => {
|
||||
this.store.update({ freeze: true })
|
||||
this.pause()
|
||||
}, 500)
|
||||
} else {
|
||||
setTimeout(() => this.freeze(), 500)
|
||||
}
|
||||
}
|
||||
|
||||
togglePlay = () => {
|
||||
const { playing, completed } = this.store.get()
|
||||
if (playing) {
|
||||
|
|
@ -189,14 +204,4 @@ export default class Animator {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: clearify logic of live time-travel
|
||||
jumpToLive = () => {
|
||||
cancelAnimationFrame(this.animationFrameRequestId)
|
||||
this.setTime(this.store.get().endTime)
|
||||
this.startAnimation()
|
||||
this.store.update({ livePlay: true })
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,8 @@ export default class MessageManager {
|
|||
private readonly session: any /*Session*/,
|
||||
private readonly state: Store<State>,
|
||||
private readonly screen: Screen,
|
||||
initialLists?: Partial<InitialLists>
|
||||
initialLists?: Partial<InitialLists>,
|
||||
coldStart?: boolean
|
||||
) {
|
||||
this.pagesManager = new PagesManager(screen, this.session.isMobile, cssLoading => {
|
||||
screen.displayFrame(!cssLoading)
|
||||
|
|
@ -138,8 +139,9 @@ export default class MessageManager {
|
|||
|
||||
this.activityManager = new ActivityManager(this.session.duration.milliseconds) // only if not-live
|
||||
|
||||
|
||||
this.loadMessages()
|
||||
if (!coldStart) {
|
||||
this.loadMessages()
|
||||
}
|
||||
}
|
||||
|
||||
private _sortMessagesHack(msgs: Message[]) {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,9 @@ export default class Screen {
|
|||
private readonly screen: HTMLDivElement;
|
||||
private parentElement: HTMLElement | null = null;
|
||||
|
||||
constructor(isMobile: boolean) {
|
||||
constructor(isMobile: boolean, coldStart?: boolean) {
|
||||
if (coldStart) return;
|
||||
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.className = styles.iframe;
|
||||
this.iframe = iframe;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export default class WebPlayer extends Player {
|
|||
|
||||
private targetMarker: TargetMarker
|
||||
|
||||
constructor(protected wpState: Store<typeof WebPlayer.INITIAL_STATE>, session: any, live: boolean) {
|
||||
constructor(protected wpState: Store<typeof WebPlayer.INITIAL_STATE>, session: any, live: boolean, coldStart?: boolean) {
|
||||
let initialLists = live ? {} : {
|
||||
event: session.events || [],
|
||||
stack: session.stackEvents || [],
|
||||
|
|
@ -40,8 +40,8 @@ export default class WebPlayer extends Player {
|
|||
) || [],
|
||||
}
|
||||
|
||||
const screen = new Screen(session.isMobile)
|
||||
const messageManager = new MessageManager(session, wpState, screen, initialLists)
|
||||
const screen = new Screen(session.isMobile, coldStart)
|
||||
const messageManager = new MessageManager(session, wpState, screen, initialLists, coldStart)
|
||||
super(wpState, messageManager)
|
||||
this.screen = screen
|
||||
this.messageManager = messageManager
|
||||
|
|
|
|||
|
|
@ -83,13 +83,13 @@ class Console extends Event {
|
|||
}
|
||||
}
|
||||
|
||||
class Click extends Event {
|
||||
export class Click extends Event {
|
||||
readonly type: typeof CLICKRAGE | typeof CLICK = CLICK;
|
||||
readonly name = 'Click'
|
||||
targetContent = '';
|
||||
count: number
|
||||
|
||||
constructor(evt: ClickEvent, isClickRage: boolean) {
|
||||
constructor(evt: ClickEvent, isClickRage?: boolean) {
|
||||
super(evt);
|
||||
this.targetContent = evt.targetContent
|
||||
this.count = evt.count
|
||||
|
|
@ -116,7 +116,6 @@ export class Location extends Event {
|
|||
readonly type = LOCATION;
|
||||
url: LocationEvent["url"]
|
||||
host: LocationEvent["host"];
|
||||
pageLoad: LocationEvent["pageLoad"];
|
||||
fcpTime: LocationEvent["fcpTime"];
|
||||
loadTime: LocationEvent["loadTime"];
|
||||
domContentLoadedTime: LocationEvent["domContentLoadedTime"];
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-nocheck
|
||||
import JSBI from 'jsbi';
|
||||
import chroma from 'chroma-js';
|
||||
import * as htmlToImage from 'html-to-image';
|
||||
|
|
|
|||
11
frontend/cypress.config.ts
Normal file
11
frontend/cypress.config.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { defineConfig } from "cypress";
|
||||
import {addMatchImageSnapshotPlugin} from 'cypress-image-snapshot/plugin';
|
||||
export default defineConfig({
|
||||
e2e: {
|
||||
baseUrl: 'http://0.0.0.0:3333/',
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
addMatchImageSnapshotPlugin(on, config)
|
||||
},
|
||||
}
|
||||
});
|
||||
4
frontend/cypress.env.example.json
Normal file
4
frontend/cypress.env.example.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"account": "test",
|
||||
"password": "test"
|
||||
}
|
||||
26
frontend/cypress/e2e/replayer.cy.ts
Normal file
26
frontend/cypress/e2e/replayer.cy.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
describe('Replayer visual match test', () => {
|
||||
it('Teklogiks sessions on 3 and 20 seconds are same', () => {
|
||||
cy.intercept('/api/account').as('getAccount')
|
||||
cy.intercept('/mobs/*').as('getSession')
|
||||
|
||||
cy.visit('/', {
|
||||
onBeforeLoad: function (window) {
|
||||
window.localStorage.setItem('notesFeatureViewed', 'true');
|
||||
}
|
||||
})
|
||||
cy.get(':nth-child(1) > .relative > .p-2').type(Cypress.env('account'))
|
||||
cy.get(':nth-child(2) > .relative > .p-2').type(Cypress.env('password'))
|
||||
cy.get('.h-10').click()
|
||||
cy.wait('@getAccount')
|
||||
cy.visit('3/session/7585361734083637?jumpto=5000&freeze=true')
|
||||
cy.wait(1000)
|
||||
|
||||
cy.matchImageSnapshot('1st-breakpoint');
|
||||
|
||||
cy.visit('3/session/7585361734083637?jumpto=20000&freeze=true')
|
||||
// adjusting because we have more messages to load
|
||||
cy.wait(3000)
|
||||
|
||||
cy.matchImageSnapshot('2nd-breakpoint');
|
||||
})
|
||||
})
|
||||
5
frontend/cypress/fixtures/example.json
Normal file
5
frontend/cypress/fixtures/example.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
||||
7
frontend/cypress/plugins/index.js
Normal file
7
frontend/cypress/plugins/index.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
const {
|
||||
addMatchImageSnapshotPlugin,
|
||||
} = require('cypress-image-snapshot/plugin');
|
||||
|
||||
module.exports = (on, config) => {
|
||||
addMatchImageSnapshotPlugin(on, config);
|
||||
};
|
||||
45
frontend/cypress/support/commands.ts
Normal file
45
frontend/cypress/support/commands.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/// <reference types="cypress" />
|
||||
// ***********************************************
|
||||
// This example commands.ts shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||
//
|
||||
// declare global {
|
||||
// namespace Cypress {
|
||||
// interface Chainable {
|
||||
// login(email: string, password: string): Chainable<void>
|
||||
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
||||
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
||||
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command';
|
||||
|
||||
addMatchImageSnapshotCommand({
|
||||
failureThreshold: 0.03, // threshold for entire image
|
||||
failureThresholdType: "percent", // percent of image or number of pixels
|
||||
customDiffConfig: { threshold: 0.1 }, // threshold for each pixel
|
||||
capture: "viewport" // capture viewport in screenshot
|
||||
});
|
||||
20
frontend/cypress/support/e2e.ts
Normal file
20
frontend/cypress/support/e2e.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// ***********************************************************
|
||||
// This example support/e2e.ts is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
|
|
@ -1,3 +1,33 @@
|
|||
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||
module.exports = {
|
||||
// "preset": "jest-puppeteer"
|
||||
}
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
moduleNameMapper: {
|
||||
'^Types/(.+)$': '<rootDir>/app/types/$1',
|
||||
'^App/(.+)$': '<rootDir>/app/$1',
|
||||
},
|
||||
transform: {
|
||||
'^.+\\.(ts|tsx)?$': ['ts-jest', { isolatedModules: true, diagnostics: { warnOnly: true } }],
|
||||
'^.+\\.(js|jsx)$': 'babel-jest',
|
||||
},
|
||||
moduleDirectories: ['node_modules', 'app'],
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
|
||||
};
|
||||
|
||||
//
|
||||
// module.exports = {
|
||||
// globals: {
|
||||
// "ts-jest": {
|
||||
// tsConfig: "tsconfig.json",
|
||||
// diagnostics: true
|
||||
// },
|
||||
// NODE_ENV: "test"
|
||||
// },
|
||||
// moduleNameMapper: {
|
||||
// "^Types/(.+)$": "<rootDir>/app/types/$1"
|
||||
// },
|
||||
// moduleDirectories: ["node_modules", 'app'],
|
||||
// moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
|
||||
|
||||
// verbose: true
|
||||
// };
|
||||
|
|
@ -15,7 +15,9 @@
|
|||
"storybook": "start-storybook -p 6006",
|
||||
"flow": "flow",
|
||||
"postinstall": "yarn gen:icons && yarn gen:colors",
|
||||
"build-storybook": "build-storybook"
|
||||
"build-storybook": "build-storybook",
|
||||
"test": "jest",
|
||||
"cy:open": "cypress open"
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/react-dom-interactions": "^0.10.3",
|
||||
|
|
@ -85,6 +87,7 @@
|
|||
"@babel/preset-react": "^7.17.12",
|
||||
"@babel/preset-typescript": "^7.17.12",
|
||||
"@babel/runtime": "^7.17.9",
|
||||
"@jest/globals": "^29.3.1",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"@openreplay/sourcemap-uploader": "^3.0.0",
|
||||
"@storybook/addon-actions": "^6.5.12",
|
||||
|
|
@ -114,6 +117,8 @@
|
|||
"country-data": "0.0.31",
|
||||
"css-loader": "^6.7.1",
|
||||
"cssnano": "^5.0.12",
|
||||
"cypress": "^12.3.0",
|
||||
"cypress-image-snapshot": "^4.0.1",
|
||||
"deasync-promise": "^1.0.1",
|
||||
"deploy-aws-s3-cloudfront": "^3.6.0",
|
||||
"dotenv": "^6.2.0",
|
||||
|
|
@ -124,6 +129,7 @@
|
|||
"file-loader": "^6.2.0",
|
||||
"flow-bin": "^0.115.0",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"jest": "^29.3.1",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
"minio": "^7.0.18",
|
||||
"moment-locales-webpack-plugin": "^1.2.0",
|
||||
|
|
@ -141,6 +147,7 @@
|
|||
"svg-inline-loader": "^0.8.2",
|
||||
"svgo": "^2.8.0",
|
||||
"tailwindcss": "^3.1.4",
|
||||
"ts-jest": "^29.0.5",
|
||||
"ts-node": "^10.7.0",
|
||||
"typescript": "^4.6.4",
|
||||
"webpack": "^5.72.1",
|
||||
|
|
|
|||
BIN
frontend/tests/mocks/devtools.mob
Normal file
BIN
frontend/tests/mocks/devtools.mob
Normal file
Binary file not shown.
BIN
frontend/tests/mocks/dom1.mobs
Normal file
BIN
frontend/tests/mocks/dom1.mobs
Normal file
Binary file not shown.
BIN
frontend/tests/mocks/dom2.mobe
Normal file
BIN
frontend/tests/mocks/dom2.mobe
Normal file
Binary file not shown.
175
frontend/tests/mocks/sessionData.js
Normal file
175
frontend/tests/mocks/sessionData.js
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
export const issues = [
|
||||
{
|
||||
issueId: '9158adad14bcb1e0db18384c778a18f5ef2',
|
||||
sessionId: 8119081922378909,
|
||||
timestamp: 1673887658753,
|
||||
seqIndex: 26901,
|
||||
payload: { Rate: 71, Duration: 20804 },
|
||||
projectId: 2325,
|
||||
type: 'cpu',
|
||||
contextString: 'https://app.openreplay.com/5095/session/8118970199817356',
|
||||
context: null,
|
||||
icon: undefined,
|
||||
key: 0,
|
||||
name: undefined,
|
||||
time: 300321,
|
||||
},
|
||||
{
|
||||
issueId: '915b2c49d8e08176a84c0d8e58732995fb8',
|
||||
sessionId: 8119081922378909,
|
||||
timestamp: 1673888064761,
|
||||
seqIndex: 74984,
|
||||
payload: { Rate: 80, Duration: 9684 },
|
||||
projectId: 2325,
|
||||
type: 'cpu',
|
||||
contextString: 'https://app.openreplay.com/5095/session/8118613089434832',
|
||||
context: null,
|
||||
icon: undefined,
|
||||
key: 1,
|
||||
name: undefined,
|
||||
time: 706329,
|
||||
},
|
||||
];
|
||||
export const events = [
|
||||
{
|
||||
time: 519,
|
||||
label: undefined,
|
||||
key: 0,
|
||||
target: { path: undefined, label: undefined },
|
||||
name: 'Location',
|
||||
type: 'LOCATION',
|
||||
sessionId: 8119081922378909,
|
||||
messageId: 14,
|
||||
timestamp: 1673887358951,
|
||||
host: 'app.openreplay.com',
|
||||
referrer: '',
|
||||
domContentLoadedTime: 1637,
|
||||
firstPaintTime: 1674,
|
||||
firstContentfulPaintTime: 1674,
|
||||
loadTime: 1870,
|
||||
speedIndex: 1889,
|
||||
visuallyComplete: 5110,
|
||||
timeToInteractive: 5328,
|
||||
domBuildingTime: 337,
|
||||
path: '/3064/sessions',
|
||||
baseReferrer: '',
|
||||
responseTime: 2,
|
||||
responseEnd: 1295,
|
||||
ttfb: null,
|
||||
query: '',
|
||||
value: '/3064/sessions',
|
||||
url: '/3064/sessions',
|
||||
fcpTime: 1674,
|
||||
},
|
||||
{
|
||||
time: 10133,
|
||||
label:
|
||||
'Inicio De Prova SESSIONS ASSIST DASHBOARDS FD Saved Search 0 Clear Search SESSIONS BOOKMARKS NOTES A',
|
||||
key: 1,
|
||||
target: { path: undefined, label: undefined },
|
||||
type: 'CLICK',
|
||||
name: 'Click',
|
||||
targetContent: undefined,
|
||||
count: undefined,
|
||||
},
|
||||
{
|
||||
time: 12287,
|
||||
label: 'Past 7 Days',
|
||||
key: 2,
|
||||
target: { path: undefined, label: undefined },
|
||||
type: 'CLICK',
|
||||
name: 'Click',
|
||||
targetContent: undefined,
|
||||
count: undefined,
|
||||
},
|
||||
{
|
||||
time: 13146,
|
||||
label: 'Search sessions using any captured event (click, input, page, error...)',
|
||||
key: 3,
|
||||
target: { path: undefined, label: undefined },
|
||||
type: 'CLICK',
|
||||
name: 'Click',
|
||||
targetContent: undefined,
|
||||
count: undefined,
|
||||
},
|
||||
{
|
||||
time: 13777,
|
||||
label:
|
||||
'Inicio De Prova Add Project Inicio De Prova Nova Proposta SESSIONS ASSIST DASHBOARDS FD INTERACTIONS',
|
||||
key: 4,
|
||||
target: { path: undefined, label: undefined },
|
||||
type: 'CLICK',
|
||||
name: 'Click',
|
||||
targetContent: undefined,
|
||||
count: undefined,
|
||||
},
|
||||
{
|
||||
time: 14440,
|
||||
label: 'Nova Proposta',
|
||||
key: 5,
|
||||
target: { path: undefined, label: undefined },
|
||||
type: 'CLICK',
|
||||
name: 'Click',
|
||||
targetContent: undefined,
|
||||
count: undefined,
|
||||
},
|
||||
{
|
||||
time: 14496,
|
||||
label: undefined,
|
||||
key: 6,
|
||||
target: { path: undefined, label: undefined },
|
||||
name: 'Location',
|
||||
type: 'LOCATION',
|
||||
sessionId: 8119081922378909,
|
||||
messageId: 2038,
|
||||
timestamp: 1673887372928,
|
||||
host: 'app.openreplay.com',
|
||||
referrer: '',
|
||||
domContentLoadedTime: null,
|
||||
firstPaintTime: null,
|
||||
firstContentfulPaintTime: null,
|
||||
loadTime: null,
|
||||
speedIndex: null,
|
||||
visuallyComplete: null,
|
||||
timeToInteractive: null,
|
||||
domBuildingTime: null,
|
||||
path: '/5095/sessions',
|
||||
baseReferrer: '',
|
||||
responseTime: null,
|
||||
responseEnd: null,
|
||||
ttfb: null,
|
||||
query: '',
|
||||
value: '/5095/sessions',
|
||||
url: '/5095/sessions',
|
||||
fcpTime: null,
|
||||
},
|
||||
{
|
||||
time: 15166,
|
||||
label: 'Search sessions using any captured event (click, input, page, error...)',
|
||||
key: 7,
|
||||
target: { path: undefined, label: undefined },
|
||||
type: 'CLICK',
|
||||
name: 'Click',
|
||||
targetContent: undefined,
|
||||
count: undefined,
|
||||
},
|
||||
{
|
||||
time: 15726,
|
||||
label: 'Search sessions using any captured event (click, input, page, error...)',
|
||||
key: 8,
|
||||
target: { path: undefined, label: undefined },
|
||||
type: 'INPUT',
|
||||
name: 'Input',
|
||||
value: 'click',
|
||||
},
|
||||
{
|
||||
time: 17270,
|
||||
label: 'Click',
|
||||
key: 9,
|
||||
target: { path: undefined, label: undefined },
|
||||
type: 'CLICK',
|
||||
name: 'Click',
|
||||
targetContent: undefined,
|
||||
count: undefined,
|
||||
},
|
||||
];
|
||||
12863
frontend/tests/mocks/sessionResponse.js
Normal file
12863
frontend/tests/mocks/sessionResponse.js
Normal file
File diff suppressed because it is too large
Load diff
8
frontend/tests/player.test.js
Normal file
8
frontend/tests/player.test.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import WebPlayer from 'App/player/web/WebPlayer';
|
||||
import SimpleStore from 'App/player/common/SimpleStore'
|
||||
|
||||
let store = new SimpleStore({
|
||||
...WebPlayer.INITIAL_STATE,
|
||||
})
|
||||
|
||||
const player = new WebPlayer(store, session, false)
|
||||
32
frontend/tests/session.test.js
Normal file
32
frontend/tests/session.test.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { describe, expect, test } from '@jest/globals';
|
||||
|
||||
import Session from 'Types/Session';
|
||||
import { Click, Location } from 'Types/Session/event';
|
||||
import Issue from 'Types/Session/issue';
|
||||
import { session } from './mocks/sessionResponse';
|
||||
import { issues, events } from "./mocks/sessionData";
|
||||
|
||||
describe('Testing Session class', () => {
|
||||
const sessionInfo = new Session(session.data);
|
||||
|
||||
test('checking type instances', () => {
|
||||
expect(sessionInfo).toBeInstanceOf(Session);
|
||||
expect(sessionInfo.issues[0]).toBeInstanceOf(Issue);
|
||||
expect(sessionInfo.events[0]).toBeInstanceOf(Location);
|
||||
expect(sessionInfo.events[1]).toBeInstanceOf(Click);
|
||||
});
|
||||
test('checking basic session info(id, userId, issues and events lengths to match)', () => {
|
||||
expect(sessionInfo.sessionId).toBe('8119081922378909');
|
||||
expect(sessionInfo.isMobile).toBe(false);
|
||||
expect(sessionInfo.userNumericHash).toBe(55003039);
|
||||
expect(sessionInfo.userId).toBe('fernando.dufour@pravaler.com.br');
|
||||
expect(sessionInfo.issues.length).toBe(2);
|
||||
expect(sessionInfo.notesWithEvents.length).toBe(362);
|
||||
});
|
||||
test('checking issue mapping', () => {
|
||||
expect([...sessionInfo.issues]).toMatchObject(issues);
|
||||
});
|
||||
test('checking events mapping', () => {
|
||||
expect([...sessionInfo.events.slice(0, 10)]).toMatchObject(events)
|
||||
})
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue