add playwright
This commit is contained in:
parent
d3d1a40909
commit
9fbe4a21e9
23 changed files with 321 additions and 107 deletions
|
|
@ -31,5 +31,5 @@ export default {
|
|||
transformIgnorePatterns: [
|
||||
'/node_modules/(?!syncod)',
|
||||
],
|
||||
setupFiles: ['<rootDir>/tests/jest.setup.ts'],
|
||||
setupFiles: ['<rootDir>/tests/unit/jest.setup.ts'],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
"@eslint/js": "^9.26.0",
|
||||
"@medv/finder": "^4.0.2",
|
||||
"@neodrag/react": "^2.3.0",
|
||||
"@playwright/test": "^1.52.0",
|
||||
"@sentry/browser": "^9.18.0",
|
||||
"@svg-maps/world": "^1.0.1",
|
||||
"@tanstack/react-query": "^5.76.0",
|
||||
|
|
@ -64,6 +65,7 @@
|
|||
"mobx": "^6.13.7",
|
||||
"mobx-persist-store": "^1.1.8",
|
||||
"mobx-react-lite": "^4.1.0",
|
||||
"playwright": "^1.52.0",
|
||||
"prismjs": "^1.30.0",
|
||||
"rc-time-picker": "^3.7.3",
|
||||
"react": "^19.1.0",
|
||||
|
|
|
|||
37
frontend/playwright.config.ts
Normal file
37
frontend/playwright.config.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import 'dotenv/config';
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: './tests/playwright',
|
||||
fullyParallel: false,
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
workers: 1,
|
||||
reporter: process.env.CI ? 'html' : 'list',
|
||||
use: {
|
||||
baseURL: 'http://localhost:3333',
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
|
||||
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
dependencies: ['setup'],
|
||||
},
|
||||
],
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: {
|
||||
command: 'yarn start',
|
||||
url: 'http://localhost:3333',
|
||||
timeout: 120 * 1000,
|
||||
},
|
||||
});
|
||||
26
frontend/tests/playwright/auth.setup.ts
Normal file
26
frontend/tests/playwright/auth.setup.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { authStateFile, testUseAuthState } from './helpers';
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
testUseAuthState();
|
||||
|
||||
test('authenticate', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
try {
|
||||
const url = page.url();
|
||||
|
||||
if (url.includes('login')) {
|
||||
await page.locator('[data-test-id="login"]').click();
|
||||
await page.locator('.ant-input-affix-wrapper').first().click();
|
||||
await page.locator('[data-test-id="login"]').fill('andrei@openreplay.com');
|
||||
await page.locator('[data-test-id="password"]').click();
|
||||
await page.locator('[data-test-id="password"]').fill('Andrey123!');
|
||||
await page.locator('[data-test-id="log-button"]').click();
|
||||
}
|
||||
await page.waitForSelector('h1:has-text("Sessions")', { timeout: 10000 });
|
||||
} catch (e) {}
|
||||
|
||||
try {
|
||||
await page.context().storageState({ path: authStateFile });
|
||||
} catch {}
|
||||
});
|
||||
18
frontend/tests/playwright/helpers.ts
Normal file
18
frontend/tests/playwright/helpers.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { mkdirSync } from "fs";
|
||||
import { exists } from "i18next";
|
||||
import { dirname } from "path";
|
||||
import { test } from "@playwright/test";
|
||||
|
||||
export const authStateFile = 'node_modules/playwright/auth-state.json';
|
||||
|
||||
mkdirSync(dirname(authStateFile), { recursive: true });
|
||||
|
||||
export function testUseAuthState() {
|
||||
if (exists(authStateFile)) {
|
||||
test.use({ storageState: authStateFile });
|
||||
}
|
||||
|
||||
test.afterEach(async ({ page }) => {
|
||||
await page.context().storageState({ path: authStateFile });
|
||||
})
|
||||
}
|
||||
13
frontend/tests/playwright/session-list.spec.ts
Normal file
13
frontend/tests/playwright/session-list.spec.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
import { testUseAuthState } from './helpers';
|
||||
|
||||
testUseAuthState();
|
||||
|
||||
test('test', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'OpenReplay Documentation Site' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Android' }).locator('div').click();
|
||||
await page.getByRole('button', { name: 'Android caret-down' }).click();
|
||||
await page.getByText('OpenReplay Documentation Site').click();
|
||||
await page.locator('#session-item').first().click();
|
||||
});
|
||||
12
frontend/tests/playwright/sign-in.spec.ts
Normal file
12
frontend/tests/playwright/sign-in.spec.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('Sign in flow', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.locator('[data-test-id="login"]').click();
|
||||
await page.locator('.ant-input-affix-wrapper').first().click();
|
||||
await page.locator('[data-test-id="login"]').fill('andrei@openreplay.com');
|
||||
await page.locator('[data-test-id="password"]').click();
|
||||
await page.locator('[data-test-id="password"]').fill('Andrey123!');
|
||||
await page.locator('[data-test-id="log-button"]').click();
|
||||
await expect(page.getByRole('heading', { name: 'Sessions' })).toBeVisible();
|
||||
});
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, test, expect, beforeEach, jest } from '@jest/globals';
|
||||
import ListWalker from '../app/player/common/ListWalker';
|
||||
import type { Timed } from '../app/player/common/types';
|
||||
import ListWalker from '../../app/player/common/ListWalker';
|
||||
import type { Timed } from '../../app/player/common/types';
|
||||
|
||||
interface Item extends Timed {
|
||||
value?: string;
|
||||
|
|
@ -17,24 +17,24 @@ describe('ListWalker', () => {
|
|||
test('append maintains order and prevents out of order inserts', () => {
|
||||
walker.append({ time: 1 });
|
||||
walker.append({ time: 3 });
|
||||
expect(walker.list.map(i => i.time)).toEqual([1, 3]);
|
||||
expect(walker.list.map((i) => i.time)).toEqual([1, 3]);
|
||||
|
||||
walker.append({ time: 2 });
|
||||
expect(walker.list.map(i => i.time)).toEqual([1, 3]);
|
||||
expect(walker.list.map((i) => i.time)).toEqual([1, 3]);
|
||||
expect((console.error as jest.Mock).mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
test('unshift prepends items', () => {
|
||||
walker.append({ time: 2 });
|
||||
walker.unshift({ time: 1 });
|
||||
expect(walker.list.map(i => i.time)).toEqual([1, 2]);
|
||||
expect(walker.list.map((i) => i.time)).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
test('insert places item according to time', () => {
|
||||
walker.append({ time: 1 });
|
||||
walker.append({ time: 3 });
|
||||
walker.insert({ time: 2 });
|
||||
expect(walker.list.map(i => i.time)).toEqual([1, 2, 3]);
|
||||
expect(walker.list.map((i) => i.time)).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
test('moveGetLast advances pointer and returns item', () => {
|
||||
|
|
@ -80,4 +80,4 @@ describe('ListWalker', () => {
|
|||
expect(collected).toEqual([1, 2, 1]);
|
||||
expect(walker.countNow).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, test, expect } from '@jest/globals';
|
||||
import MFileReader from '../app/player/web/messages/MFileReader';
|
||||
import { MType } from '../app/player/web/messages/raw.gen';
|
||||
import MFileReader from '../../app/player/web/messages/MFileReader';
|
||||
import { MType } from '../../app/player/web/messages/raw.gen';
|
||||
|
||||
function encodeUint(value: number): Uint8Array {
|
||||
const bytes: number[] = [];
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
import { describe, expect, test, jest, beforeEach } from '@jest/globals';
|
||||
import MessageLoader from '../app/player/web/MessageLoader';
|
||||
import { MType } from '../app/player/web/messages';
|
||||
import MessageLoader from '../../app/player/web/MessageLoader';
|
||||
import { MType } from '../../app/player/web/messages';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { TextDecoder } from 'util';
|
||||
|
||||
const loadFilesMock = jest.fn(async () => {});
|
||||
|
||||
jest.mock('../app/player/web/network/loadFiles', () => ({
|
||||
jest.mock('../../app/player/web/network/loadFiles', () => ({
|
||||
__esModule: true,
|
||||
loadFiles: jest.fn(async () => {}),
|
||||
requestTarball: jest.fn(),
|
||||
|
|
@ -17,7 +17,7 @@ jest.mock('../app/player/web/network/loadFiles', () => ({
|
|||
|
||||
const decryptSessionBytesMock = jest.fn((b: Uint8Array) => Promise.resolve(b));
|
||||
|
||||
jest.mock('../app/player/web/network/crypto', () => ({
|
||||
jest.mock('../../app/player/web/network/crypto', () => ({
|
||||
__esModule: true,
|
||||
decryptSessionBytes: jest.fn((b: Uint8Array) => Promise.resolve(b)),
|
||||
}));
|
||||
|
|
@ -32,11 +32,11 @@ jest.mock('Player/common/tarball', () => ({
|
|||
default: jest.fn((b: Uint8Array) => b),
|
||||
}));
|
||||
|
||||
import MFileReader from '../app/player/web/messages/MFileReader';
|
||||
import MFileReader from '../../app/player/web/messages/MFileReader';
|
||||
|
||||
const readNextMock = jest.fn();
|
||||
|
||||
jest.mock('../app/player/web/messages/MFileReader', () => {
|
||||
jest.mock('../../app/player/web/messages/MFileReader', () => {
|
||||
return {
|
||||
__esModule: true,
|
||||
default: jest.fn().mockImplementation(() => {
|
||||
|
|
@ -49,7 +49,7 @@ jest.mock('../app/player/web/messages/MFileReader', () => {
|
|||
};
|
||||
});
|
||||
|
||||
import { mockSession } from './mocks/sessionData';
|
||||
import { mockSession } from '../mocks/sessionData';
|
||||
|
||||
const createStore = () => {
|
||||
const state: Record<string, any> = {};
|
||||
|
|
@ -1,20 +1,24 @@
|
|||
import { it, expect, beforeEach, jest } from '@jest/globals';
|
||||
import TabSessionManager from '../app/player/web/TabManager';
|
||||
import SimpleStore from '../app/player/common/SimpleStore';
|
||||
import { TYPES as EVENT_TYPES } from '../app/types/session/event';
|
||||
import { MType } from '../app/player/web/messages/raw.gen';
|
||||
import TabSessionManager from '../../app/player/web/TabManager';
|
||||
import SimpleStore from '../../app/player/common/SimpleStore';
|
||||
import { TYPES as EVENT_TYPES } from '../../app/types/session/event';
|
||||
import { MType } from '../../app/player/web/messages/raw.gen';
|
||||
|
||||
jest.mock('@medv/finder', () => ({ default: jest.fn(() => 'mocked network-proxy content') }));
|
||||
jest.mock('@medv/finder', () => ({
|
||||
default: jest.fn(() => 'mocked network-proxy content'),
|
||||
}));
|
||||
jest.mock('syncod', () => {
|
||||
return {
|
||||
Decoder: jest.fn().mockImplementation(() => ({ decode: jest.fn(), set: jest.fn() })),
|
||||
Decoder: jest
|
||||
.fn()
|
||||
.mockImplementation(() => ({ decode: jest.fn(), set: jest.fn() })),
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('js-untar', () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn(),
|
||||
}));
|
||||
__esModule: true,
|
||||
default: jest.fn(),
|
||||
}));
|
||||
|
||||
class FakeScreen {
|
||||
displayFrame = jest.fn();
|
||||
|
|
@ -35,7 +39,14 @@ beforeEach(() => {
|
|||
tabNames: {},
|
||||
eventCount: 0,
|
||||
});
|
||||
manager = new TabSessionManager(session, store as any, new FakeScreen() as any, 'tab1', setSize, 0);
|
||||
manager = new TabSessionManager(
|
||||
session,
|
||||
store as any,
|
||||
new FakeScreen() as any,
|
||||
'tab1',
|
||||
setSize,
|
||||
0,
|
||||
);
|
||||
jest.runOnlyPendingTimers();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
|
@ -65,14 +76,21 @@ it('resetMessageManagers should clear managers', () => {
|
|||
});
|
||||
|
||||
it('onFileReadSuccess should update store with lists and performance data', () => {
|
||||
(manager as any).performanceTrackManager['chart'] = [{ time: 1, usedHeap: 0, totalHeap: 0, fps: null, cpu: null, nodesCount: 0 }];
|
||||
(manager as any).performanceTrackManager['chart'] = [
|
||||
{ time: 1, usedHeap: 0, totalHeap: 0, fps: null, cpu: null, nodesCount: 0 },
|
||||
];
|
||||
(manager as any).performanceTrackManager['cpuAvailable'] = true;
|
||||
(manager as any).performanceTrackManager['fpsAvailable'] = true;
|
||||
manager.locationManager.append({ time: 2, url: 'http://example.com' } as any);
|
||||
manager.onFileReadSuccess();
|
||||
const state = store.get().tabStates['tab1'];
|
||||
expect(state.performanceChartData.length).toBe(1);
|
||||
expect(state.performanceAvailability).toEqual({ cpu: true, fps: true, heap: false, nodes: true });
|
||||
expect(state.performanceAvailability).toEqual({
|
||||
cpu: true,
|
||||
fps: true,
|
||||
heap: false,
|
||||
nodes: true,
|
||||
});
|
||||
expect(state.urlsList[0].url).toBe('http://example.com');
|
||||
});
|
||||
|
||||
|
|
@ -98,4 +116,4 @@ it('sortDomRemoveMessages comparator should prioritize head nodes', () => {
|
|||
expect(comparator(msgs[2], msgs[0])).toBe(1);
|
||||
expect(comparator(msgs[0], msgs[1])).toBe(-1);
|
||||
expect(comparator(msgs[1], msgs[0])).toBe(1);
|
||||
});
|
||||
});
|
||||
|
|
@ -33,17 +33,17 @@ class MockWebLivePlayer {
|
|||
) {}
|
||||
}
|
||||
|
||||
jest.mock('../app/player/mobile/IOSPlayer', () => ({
|
||||
jest.mock('../../app/player/mobile/IOSPlayer', () => ({
|
||||
__esModule: true,
|
||||
default: MockIOSPlayer,
|
||||
}));
|
||||
|
||||
jest.mock('../app/player/web/WebPlayer', () => ({
|
||||
jest.mock('../../app/player/web/WebPlayer', () => ({
|
||||
__esModule: true,
|
||||
default: MockWebPlayer,
|
||||
}));
|
||||
|
||||
jest.mock('../app/player/web/WebLivePlayer', () => ({
|
||||
jest.mock('../../app/player/web/WebLivePlayer', () => ({
|
||||
__esModule: true,
|
||||
default: MockWebLivePlayer,
|
||||
}));
|
||||
|
|
@ -54,7 +54,7 @@ import {
|
|||
createClickMapPlayer,
|
||||
createLiveWebPlayer,
|
||||
createClipPlayer,
|
||||
} from '../app/player/create';
|
||||
} from '../../app/player/create';
|
||||
|
||||
const session = { id: 1 } as any;
|
||||
const errorHandler = { error: jest.fn() };
|
||||
|
|
@ -1,28 +1,30 @@
|
|||
import FeatureFlag, { Conditions, Variant } from '../app/mstore/types/FeatureFlag';
|
||||
import FeatureFlag, {
|
||||
Conditions,
|
||||
Variant,
|
||||
} from '../../app/mstore/types/FeatureFlag';
|
||||
import { jest, test, expect, describe } from '@jest/globals';
|
||||
|
||||
|
||||
jest.mock('App/mstore/types/filter', () => {
|
||||
let filterData = { filters: [] }
|
||||
let filterData = { filters: [] };
|
||||
|
||||
class MockFilter {
|
||||
ID_KEY = "filterId"
|
||||
filterId = ''
|
||||
name = ''
|
||||
filters = []
|
||||
eventsOrder = 'then'
|
||||
eventsOrderSupport = ['then', 'or', 'and']
|
||||
startTimestamp = 0
|
||||
endTimestamp = 0
|
||||
ID_KEY = 'filterId';
|
||||
filterId = '';
|
||||
name = '';
|
||||
filters = [];
|
||||
eventsOrder = 'then';
|
||||
eventsOrderSupport = ['then', 'or', 'and'];
|
||||
startTimestamp = 0;
|
||||
endTimestamp = 0;
|
||||
fromJson(json) {
|
||||
this.name = json.name
|
||||
this.filters = json.filters.map((i) => i)
|
||||
this.eventsOrder = json.eventsOrder
|
||||
return this
|
||||
this.name = json.name;
|
||||
this.filters = json.filters.map((i) => i);
|
||||
this.eventsOrder = json.eventsOrder;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return MockFilter
|
||||
})
|
||||
return MockFilter;
|
||||
});
|
||||
|
||||
describe('Feature flag type test', () => {
|
||||
// Test cases for Conditions class
|
||||
|
|
@ -37,9 +37,27 @@ jest.mock('Types/filter/newFilter', () => {
|
|||
const { FilterKey, FilterCategory } = require('Types/filter/filterType');
|
||||
return {
|
||||
filtersMap: {
|
||||
[FilterKey.USERID]: { key: FilterKey.USERID, type: FilterKey.USERID, category: FilterCategory.USER, operator: 'is', value: [''] },
|
||||
[FilterKey.DURATION]: { key: FilterKey.DURATION, type: FilterKey.DURATION, category: FilterCategory.SESSION, operator: 'is', value: [0, 0] },
|
||||
[FilterKey.ISSUE]: { key: FilterKey.ISSUE, type: FilterKey.ISSUE, category: FilterCategory.ISSUE, operator: 'is', value: [] },
|
||||
[FilterKey.USERID]: {
|
||||
key: FilterKey.USERID,
|
||||
type: FilterKey.USERID,
|
||||
category: FilterCategory.USER,
|
||||
operator: 'is',
|
||||
value: [''],
|
||||
},
|
||||
[FilterKey.DURATION]: {
|
||||
key: FilterKey.DURATION,
|
||||
type: FilterKey.DURATION,
|
||||
category: FilterCategory.SESSION,
|
||||
operator: 'is',
|
||||
value: [0, 0],
|
||||
},
|
||||
[FilterKey.ISSUE]: {
|
||||
key: FilterKey.ISSUE,
|
||||
type: FilterKey.ISSUE,
|
||||
category: FilterCategory.ISSUE,
|
||||
operator: 'is',
|
||||
value: [],
|
||||
},
|
||||
},
|
||||
conditionalFiltersMap: {},
|
||||
generateFilterOptions: jest.fn(() => []),
|
||||
|
|
@ -51,27 +69,31 @@ jest.mock('Types/filter/newFilter', () => {
|
|||
const mockSessionFetch = jest.fn().mockResolvedValue({});
|
||||
|
||||
const mockSessionStore = {
|
||||
fetchSessions: mockSessionFetch,
|
||||
total: 0,
|
||||
clearList: jest.fn(),
|
||||
};
|
||||
const mockSettingsStore = {
|
||||
sessionSettings: { durationFilter: { count: 0 } },
|
||||
};
|
||||
fetchSessions: mockSessionFetch,
|
||||
total: 0,
|
||||
clearList: jest.fn(),
|
||||
};
|
||||
const mockSettingsStore = {
|
||||
sessionSettings: { durationFilter: { count: 0 } },
|
||||
};
|
||||
|
||||
jest.mock('App/services', () => ({
|
||||
searchService: { fetchSavedSearch: jest.fn() },
|
||||
sessionService: { getSessions: jest.fn().mockResolvedValue({ sessions: [], total: 0 }) },
|
||||
sessionService: {
|
||||
getSessions: jest.fn().mockResolvedValue({ sessions: [], total: 0 }),
|
||||
},
|
||||
}));
|
||||
jest.mock('App/mstore', () => ({
|
||||
sessionStore: mockSessionStore,
|
||||
settingsStore: mockSettingsStore,
|
||||
}));
|
||||
|
||||
import SearchStore, { checkValues, filterMap } from '../app/mstore/searchStore';
|
||||
import SavedSearch from '../app/mstore/types/savedSearch';
|
||||
import { FilterCategory, FilterKey } from '../app/types/filter/filterType';
|
||||
|
||||
import SearchStore, {
|
||||
checkValues,
|
||||
filterMap,
|
||||
} from '../../app/mstore/searchStore';
|
||||
import SavedSearch from '../../app/mstore/types/savedSearch';
|
||||
import { FilterCategory, FilterKey } from '../../app/types/filter/filterType';
|
||||
|
||||
describe('searchStore utilities', () => {
|
||||
it('checkValues handles duration', () => {
|
||||
|
|
@ -113,7 +135,9 @@ describe('SearchStore class', () => {
|
|||
it('applySavedSearch sets filters', () => {
|
||||
const saved = new SavedSearch({
|
||||
name: 'test',
|
||||
filter: { filters: [{ key: FilterKey.USERID, value: ['123'], operator: 'is' }] },
|
||||
filter: {
|
||||
filters: [{ key: FilterKey.USERID, value: ['123'], operator: 'is' }],
|
||||
},
|
||||
});
|
||||
store.applySavedSearch(saved);
|
||||
expect(store.savedSearch).toBe(saved);
|
||||
|
|
@ -129,11 +153,17 @@ describe('SearchStore class', () => {
|
|||
});
|
||||
|
||||
it('fetchSessions applies duration filter from settings', async () => {
|
||||
mockSettingsStore.sessionSettings.durationFilter = { operator: '<', count: 1, countType: 'sec' };
|
||||
mockSettingsStore.sessionSettings.durationFilter = {
|
||||
operator: '<',
|
||||
count: 1,
|
||||
countType: 'sec',
|
||||
};
|
||||
await store.fetchSessions();
|
||||
const call = mockSessionFetch.mock.calls[0][0];
|
||||
const duration = call.filters.find((f: any) => f.type === FilterKey.DURATION);
|
||||
const duration = call.filters.find(
|
||||
(f: any) => f.type === FilterKey.DURATION,
|
||||
);
|
||||
expect(duration).toBeTruthy();
|
||||
expect(duration.value).toEqual([1000, 0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
import { describe, expect, test } from '@jest/globals';
|
||||
|
||||
import Session from '../app/types/session';
|
||||
import { Click, Location } from '../app/types/session/event';
|
||||
import Issue from '../app/types/session/issue';
|
||||
import { session } from './mocks/sessionResponse';
|
||||
import { issues, events } from "./mocks/sessionData";
|
||||
import Session from '../../app/types/session';
|
||||
import { Click, Location } from '../../app/types/session/event';
|
||||
import Issue from '../../app/types/session/issue';
|
||||
import { session } from '../mocks/sessionResponse';
|
||||
import { issues, events } from '../mocks/sessionData';
|
||||
|
||||
describe('Testing Session class', () => {
|
||||
const sessionInfo = new Session(session.data);
|
||||
|
|
@ -27,6 +27,6 @@ describe('Testing Session class', () => {
|
|||
expect([...sessionInfo.issues]).toMatchObject(issues);
|
||||
});
|
||||
test('checking events mapping', () => {
|
||||
expect([...sessionInfo.events.slice(0, 10)]).toMatchObject(events)
|
||||
})
|
||||
expect([...sessionInfo.events.slice(0, 10)]).toMatchObject(events);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
import { sessionService } from '../app/services';
|
||||
import Session from '../app/types/session'
|
||||
import { sessionService } from '../../app/services';
|
||||
import Session from '../../app/types/session';
|
||||
import { beforeEach, describe, expect, it, jest } from '@jest/globals';
|
||||
import SessionStore from '../app/mstore/sessionStore';
|
||||
import { searchStore } from '../app/mstore/index';
|
||||
import { checkEventWithFilters } from '../app/components/Session_/Player/Controls/checkEventWithFilters';
|
||||
import { mockSession } from './mocks/sessionData';
|
||||
import SessionStore from '../../app/mstore/sessionStore';
|
||||
import { searchStore } from '../../app/mstore/index';
|
||||
import { checkEventWithFilters } from '../../app/components/Session_/Player/Controls/checkEventWithFilters';
|
||||
import { mockSession } from '../mocks/sessionData';
|
||||
|
||||
jest.mock('../app/player', () => ({
|
||||
jest.mock('../../app/player', () => ({
|
||||
createWebPlayer: jest.fn(),
|
||||
createIOSPlayer: jest.fn(),
|
||||
createClickMapPlayer: jest.fn(),
|
||||
createLiveWebPlayer: jest.fn(),
|
||||
createClipPlayer: jest.fn()
|
||||
createClipPlayer: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('../app/services', () => ({
|
||||
jest.mock('../../app/services', () => ({
|
||||
sessionService: {
|
||||
getSessions: jest.fn(),
|
||||
getLiveSessions: jest.fn(),
|
||||
|
|
@ -41,7 +41,7 @@ jest.mock(
|
|||
}),
|
||||
);
|
||||
|
||||
jest.mock('../app/mstore/index', () => ({
|
||||
jest.mock('../../app/mstore/index', () => ({
|
||||
searchStore: {
|
||||
instance: {
|
||||
filters: [],
|
||||
|
|
@ -2,7 +2,7 @@ import { jest, beforeEach, describe, expect, it } from '@jest/globals';
|
|||
|
||||
import spotPlayerStore, {
|
||||
PANELS,
|
||||
} from '../app/components/Spots/SpotPlayer/spotPlayerStore';
|
||||
} from '../../app/components/Spots/SpotPlayer/spotPlayerStore';
|
||||
|
||||
jest.mock('App/player', () => ({
|
||||
getResourceFromNetworkRequest: jest.fn(),
|
||||
|
|
@ -6,11 +6,11 @@ import {
|
|||
Resource,
|
||||
getResourceFromResourceTiming,
|
||||
getResourceFromNetworkRequest,
|
||||
} from '../app/player/web/types/resource';
|
||||
} from '../../app/player/web/types/resource';
|
||||
import type {
|
||||
ResourceTiming,
|
||||
NetworkRequest,
|
||||
} from '../app/player/web/messages';
|
||||
} from '../../app/player/web/messages';
|
||||
import { test, describe, expect } from '@jest/globals';
|
||||
|
||||
describe('getURLExtention', () => {
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
import { test, describe, expect } from "@jest/globals";
|
||||
import { resolveCSS } from '../app/player/web/messages/rewriter/urlResolve';
|
||||
import { test, describe, expect } from '@jest/globals';
|
||||
import { resolveCSS } from '../../app/player/web/messages/rewriter/urlResolve';
|
||||
|
||||
const strings = [
|
||||
`@import "custom.css";`,
|
||||
`@import url("chrome://communicator/skin/");`,
|
||||
`@import '../app/custom.css';`,
|
||||
`@import '../../app/custom.css';`,
|
||||
`@import "styles/common.css";`,
|
||||
`@import "/css/commonheader.css";`,
|
||||
`@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;700;900&display=swap');`,
|
||||
|
|
@ -13,26 +13,26 @@ const strings = [
|
|||
#login-required {
|
||||
color: #fff;
|
||||
};`,
|
||||
`@import url("style.css") screen and (max-width: 600px);`
|
||||
`@import url("style.css") screen and (max-width: 600px);`,
|
||||
];
|
||||
const testStrings = [
|
||||
`@import url("https://example.com/custom.css");`,
|
||||
`@import url("chrome://communicator/skin/");`,
|
||||
`@import url('https://example.com/app/custom.css');`,
|
||||
`@import url("https://example.com/styles/common.css");`,
|
||||
`@import url("https://example.com/css/commonheader.css");`,
|
||||
`@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;700;900&display=swap');`,
|
||||
`@import url('https://example.com/css/onboardcustom.css');
|
||||
`@import url("https://example.com/custom.css");`,
|
||||
`@import url("chrome://communicator/skin/");`,
|
||||
`@import url('https://example.com/app/custom.css');`,
|
||||
`@import url("https://example.com/styles/common.css");`,
|
||||
`@import url("https://example.com/css/commonheader.css");`,
|
||||
`@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;700;900&display=swap');`,
|
||||
`@import url('https://example.com/css/onboardcustom.css');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;700;900&display=swap');
|
||||
#login-required {
|
||||
color: #fff;
|
||||
};`,
|
||||
`@import url("https://example.com/style.css") screen and (max-width: 600px);`
|
||||
]
|
||||
`@import url("https://example.com/style.css") screen and (max-width: 600px);`,
|
||||
];
|
||||
describe('resolveCSS', () => {
|
||||
test('should rewrite the CSS with the correct URLs', () => {
|
||||
strings.forEach((string, i) => {
|
||||
expect(resolveCSS('https://example.com', string)).toBe(testStrings[i]);
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -39,6 +39,6 @@
|
|||
"app/**/*.jsx",
|
||||
"window.d.ts",
|
||||
"cypress/snapshots/sessionStore.test.ts",
|
||||
"tests/create.test.ts"
|
||||
"tests/unit/create.test.ts"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2889,6 +2889,17 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@playwright/test@npm:^1.52.0":
|
||||
version: 1.52.0
|
||||
resolution: "@playwright/test@npm:1.52.0"
|
||||
dependencies:
|
||||
playwright: "npm:1.52.0"
|
||||
bin:
|
||||
playwright: cli.js
|
||||
checksum: 10c1/b7a57ce045e246d927cc8cd2091864313be6e778cc6e9f2484e6273ce091fd6eb8a68c177cf6cbd484dda68a4fa85dfaa8109ae2618475c0f07f6447b3988379
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rc-component/async-validator@npm:^5.0.3":
|
||||
version: 5.0.4
|
||||
resolution: "@rc-component/async-validator@npm:5.0.4"
|
||||
|
|
@ -8669,6 +8680,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fsevents@npm:2.3.2":
|
||||
version: 2.3.2
|
||||
resolution: "fsevents@npm:2.3.2"
|
||||
dependencies:
|
||||
node-gyp: "npm:latest"
|
||||
checksum: 10c1/39f892d6e26b3d01f7e18fac9dd334d2c2a250ac2d534066e033dc5081c669b6c8b9e61f8ceb396fd9aafc210a2a3f56d8c9064768db1c1d2f34ad985c6d5b02
|
||||
conditions: os=darwin
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2":
|
||||
version: 2.3.3
|
||||
resolution: "fsevents@npm:2.3.3"
|
||||
|
|
@ -8679,6 +8700,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin<compat/fsevents>":
|
||||
version: 2.3.2
|
||||
resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin<compat/fsevents>::version=2.3.2&hash=df0bf1"
|
||||
dependencies:
|
||||
node-gyp: "npm:latest"
|
||||
conditions: os=darwin
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin<compat/fsevents>, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin<compat/fsevents>":
|
||||
version: 2.3.3
|
||||
resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin<compat/fsevents>::version=2.3.3&hash=df0bf1"
|
||||
|
|
@ -12885,6 +12915,7 @@ __metadata:
|
|||
"@medv/finder": "npm:^4.0.2"
|
||||
"@neodrag/react": "npm:^2.3.0"
|
||||
"@openreplay/sourcemap-uploader": "npm:^3.0.10"
|
||||
"@playwright/test": "npm:^1.52.0"
|
||||
"@sentry/browser": "npm:^9.18.0"
|
||||
"@svg-maps/world": "npm:^1.0.1"
|
||||
"@tanstack/react-query": "npm:^5.76.0"
|
||||
|
|
@ -12957,6 +12988,7 @@ __metadata:
|
|||
mobx-persist-store: "npm:^1.1.8"
|
||||
mobx-react-lite: "npm:^4.1.0"
|
||||
node-gyp: "npm:^9.0.0"
|
||||
playwright: "npm:^1.52.0"
|
||||
postcss: "npm:^8.5.3"
|
||||
postcss-import: "npm:^16.1.0"
|
||||
postcss-loader: "npm:^8.1.1"
|
||||
|
|
@ -13416,6 +13448,30 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"playwright-core@npm:1.52.0":
|
||||
version: 1.52.0
|
||||
resolution: "playwright-core@npm:1.52.0"
|
||||
bin:
|
||||
playwright-core: cli.js
|
||||
checksum: 10c1/86d3a13d6a5e426757bfd620f87f52696cec42f1e6e39e40d595b8cbab602447d1e309ad67f51e03ced147677de7824518abb9587254fb14c8b4252b7b1bae2a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"playwright@npm:1.52.0, playwright@npm:^1.52.0":
|
||||
version: 1.52.0
|
||||
resolution: "playwright@npm:1.52.0"
|
||||
dependencies:
|
||||
fsevents: "npm:2.3.2"
|
||||
playwright-core: "npm:1.52.0"
|
||||
dependenciesMeta:
|
||||
fsevents:
|
||||
optional: true
|
||||
bin:
|
||||
playwright: cli.js
|
||||
checksum: 10c1/58f5fa976f733fd64fba716f2e605cfd1fcdffc9f874f4baa657330ff9c4e9f8b1d49c02d33fbcea48c40472cc5ed07dec8d0291dac38cc2ed579449c0053ee5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"plist@npm:^3.0.1":
|
||||
version: 3.1.0
|
||||
resolution: "plist@npm:3.1.0"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue