E2e tests frontend (#3471)
* add playwright * add e2e test * add test * add e2e test * add e2e tests
This commit is contained in:
parent
85f6551b32
commit
09c98b5bde
32 changed files with 541 additions and 109 deletions
|
|
@ -215,6 +215,7 @@ export function GridItem({
|
|||
className={`bg-white rounded-lg overflow-hidden shadow-sm border ${
|
||||
isSelected ? 'border-teal/30' : ''
|
||||
} transition flex flex-col items-start hover:border-teal`}
|
||||
data-test-id="spot-list-item"
|
||||
>
|
||||
<div
|
||||
className="relative group overflow-hidden"
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ function ProjectDropdown(props: { location: any }) {
|
|||
}}
|
||||
placement="bottomLeft"
|
||||
>
|
||||
<Button>
|
||||
<Button data-test-id="project-dropdown" >
|
||||
<Space>
|
||||
<Text className="font-medium capitalize">
|
||||
{showCurrent && activeSite ? (
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ function SelectDateRange(props: Props) {
|
|||
isUSLocale={isUSLocale}
|
||||
useButtonStyle={useButtonStyle}
|
||||
isTileDisabled={isTileDisabled}
|
||||
data-test-id="widget-select-date-range"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -164,6 +165,7 @@ function SelectDateRange(props: Props) {
|
|||
period={period}
|
||||
right
|
||||
style={{ width: '100%' }}
|
||||
data-test-id="widget-select-date-range"
|
||||
/>
|
||||
{isCustom && (
|
||||
<OutsideClickDetectingDiv
|
||||
|
|
@ -272,6 +274,7 @@ function AndDateRange({
|
|||
size="small"
|
||||
className="flex items-center btn-card-period-range"
|
||||
icon={useButtonStyle ? <Calendar size={16} /> : null}
|
||||
data-test-id="widget-select-date-range"
|
||||
>
|
||||
{isCustomRange ? customRange : selectedValue?.label}
|
||||
<DownOutlined />
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ function SessionHeader() {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center px-4 py-3 justify-between w-full">
|
||||
<div className="flex items-center px-4 py-3 justify-between w-full" data-test-id="session-list-header">
|
||||
<div
|
||||
className={`flex w-full flex-wrap gap-2 ${screens.md ? 'justify-between' : 'justify-start'}`}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -31,5 +31,9 @@ export default {
|
|||
transformIgnorePatterns: [
|
||||
'/node_modules/(?!syncod)',
|
||||
],
|
||||
setupFiles: ['<rootDir>/tests/jest.setup.ts'],
|
||||
setupFiles: ['<rootDir>/tests/unit/jest.setup.ts'],
|
||||
testPathIgnorePatterns: [
|
||||
'/node_modules/',
|
||||
'/tests/playwright/'
|
||||
],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,6 +29,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",
|
||||
|
|
@ -65,6 +66,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: true,
|
||||
retries: 0,
|
||||
workers: 1,
|
||||
reporter: '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,
|
||||
reuseExistingServer: true,
|
||||
},
|
||||
});
|
||||
70
frontend/tests/playwright/auth-state.json
Normal file
70
frontend/tests/playwright/auth-state.json
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"cookies": [],
|
||||
"origins": [
|
||||
{
|
||||
"origin": "http://localhost:3333",
|
||||
"localStorage": [
|
||||
{
|
||||
"name": "__$session-timezone$_local__",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "i18nextLng",
|
||||
"value": "en"
|
||||
},
|
||||
{
|
||||
"name": "theme",
|
||||
"value": "light"
|
||||
},
|
||||
{
|
||||
"name": "__$user-gettingStarted$__",
|
||||
"value": "{\"steps\":[{\"title\":\"🛠️ Install OpenReplay\",\"status\":\"completed\"},{\"title\":\"🕵️ Identify Users\",\"status\":\"completed\"},{\"title\":\"🧑💻 Invite Team Members\",\"status\":\"completed\"},{\"title\":\"🔌 Integrations\",\"status\":\"completed\"}],\"status\":\"completed\"}"
|
||||
},
|
||||
{
|
||||
"name": "__$global-destinationPath$__",
|
||||
"value": "/"
|
||||
},
|
||||
{
|
||||
"name": "___$or_spotToken$___",
|
||||
"value": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjU4LCJ0ZW5hbnRJZCI6MSwiZXhwIjoxNzQ4ODc2MzkyLCJpc3MiOiJPcGVuUmVwbGF5LW9zcyIsImlhdCI6MTc0ODg3NTc5MiwiYXVkIjoic3BvdDpPcGVuUmVwbGF5In0.5Xuboo2h30P6mTYHEtzoaJTBZvZGwEMs8ywookDsY0Xp0Ah9m9K-s3WF2x-M_7LCfDOp7nBFa8j9AyKz09V0oA"
|
||||
},
|
||||
{
|
||||
"name": "__$session-timezone$__",
|
||||
"value": "{\"label\":\"UTC +02:00\",\"value\":\"UTC+02\"}"
|
||||
},
|
||||
{
|
||||
"name": "__$session-mouseTrail$__",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "__openreplay_health_status",
|
||||
"value": "1748875801944"
|
||||
},
|
||||
{
|
||||
"name": "__$user-siteId$__",
|
||||
"value": "109"
|
||||
},
|
||||
{
|
||||
"name": "__or__langBannerClosed",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": "AuthStore",
|
||||
"value": "{\"authDetails\":\"{\\\"tenants\\\":true,\\\"sso\\\":null,\\\"ssoProvider\\\":null,\\\"enforceSSO\\\":null,\\\"edition\\\":\\\"foss\\\"}\",\"__mps__\":{\"expireInTimestamp\":1748879400231}}"
|
||||
},
|
||||
{
|
||||
"name": "UserStore",
|
||||
"value": "{\"siteId\":null,\"tenants\":[],\"jwt\":\"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjU4LCJ0ZW5hbnRJZCI6MSwiZXhwIjoxNzQ4OTYyMTkyLCJpc3MiOiJPcGVuUmVwbGF5LW9zcyIsImlhdCI6MTc0ODg3NTc5MiwiYXVkIjoiZnJvbnQ6T3BlblJlcGxheSJ9.bfMw80k15BIwHkR_JQsY_DFqDJwERZcpYLOBRbcPcm2OT_WPozDal6HS8rs5YeyW0m98HRJa1ShGoMiyQhxMJA\",\"spotJwt\":\"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjU4LCJ0ZW5hbnRJZCI6MSwiZXhwIjoxNzQ4ODc2MzkyLCJpc3MiOiJPcGVuUmVwbGF5LW9zcyIsImlhdCI6MTc0ODg3NTc5MiwiYXVkIjoic3BvdDpPcGVuUmVwbGF5In0.5Xuboo2h30P6mTYHEtzoaJTBZvZGwEMs8ywookDsY0Xp0Ah9m9K-s3WF2x-M_7LCfDOp7nBFa8j9AyKz09V0oA\",\"scopeState\":2,\"onboarding\":false,\"account\":\"{\\\"id\\\":58,\\\"email\\\":\\\"andrei@openreplay.com\\\",\\\"smtp\\\":false,\\\"expirationDate\\\":-1,\\\"permissions\\\":[],\\\"settings\\\":{\\\"modules\\\":[\\\"usability-tests\\\",\\\"feature-flags\\\"]},\\\"iceServers\\\":[],\\\"hasPassword\\\":true,\\\"apiKey\\\":\\\"48Vph82zUEWHmfPSUbgG\\\",\\\"edition\\\":\\\"foss\\\",\\\"optOut\\\":false,\\\"versionNumber\\\":\\\"1.17.0\\\",\\\"name\\\":\\\"Andrei\\\",\\\"createdAt\\\":1652690354756,\\\"admin\\\":true,\\\"superAdmin\\\":false}\"}"
|
||||
},
|
||||
{
|
||||
"name": "__openreplay_health_response",
|
||||
"value": "{\"overallHealth\":true,\"healthMap\":{\"databases\":{\"name\":\"Databases\",\"healthOk\":true,\"subservices\":{\"postgres\":{\"health\":true,\"details\":{}}},\"serviceName\":\"databases\"},\"ingestionPipeline\":{\"name\":\"Ingestion Pipeline\",\"healthOk\":true,\"subservices\":{\"redis\":{\"health\":true,\"details\":{}}},\"serviceName\":\"ingestionPipeline\"},\"backendServices\":{\"name\":\"Backend Services\",\"healthOk\":true,\"subservices\":{\"alerts\":{\"health\":true,\"details\":{}},\"assets\":{\"health\":true,\"details\":{}},\"assist\":{\"health\":true,\"details\":{}},\"chalice\":{\"health\":true,\"details\":{}},\"db\":{\"health\":true,\"details\":{}},\"ender\":{\"health\":true,\"details\":{}},\"frontend\":{\"health\":true,\"details\":{}},\"heuristics\":{\"health\":true,\"details\":{}},\"http\":{\"health\":true,\"details\":{}},\"ingress-nginx\":{\"health\":true,\"details\":{}},\"integrations\":{\"health\":true,\"details\":{}},\"sink\":{\"health\":true,\"details\":{}},\"sourcemapreader\":{\"health\":true,\"details\":{}},\"storage\":{\"health\":true,\"details\":{}}},\"serviceName\":\"backendServices\"}},\"details\":{\"numberOfSessionsCaptured\":216638,\"numberOfEventCaptured\":1840149}}"
|
||||
},
|
||||
{
|
||||
"name": "__$session-filter$__",
|
||||
"value": "{\"name\":\"\",\"events\":[],\"custom\":{},\"rangeValue\":\"LAST_24_HOURS\",\"startDate\":1748790000000,\"endDate\":1748876400000,\"groupByUser\":false,\"sort\":\"startTs\",\"order\":\"desc\",\"strict\":false,\"eventsOrder\":\"then\",\"limit\":10,\"page\":1,\"perPage\":10,\"tab\":\"sessions\",\"filters\":[]}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
38
frontend/tests/playwright/auth.setup.ts
Normal file
38
frontend/tests/playwright/auth.setup.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { authStateFile, testUseAuthState } from './helpers';
|
||||
import { expect, test as setup } from '@playwright/test';
|
||||
|
||||
testUseAuthState();
|
||||
|
||||
setup.beforeEach(async ({ page }) => {
|
||||
await page.goto('http://localhost:3333');
|
||||
});
|
||||
|
||||
setup('authenticate', async ({ page }) => {
|
||||
await page.goto('/login');
|
||||
|
||||
try {
|
||||
const url = page.url();
|
||||
console.log('Current URL:', url);
|
||||
|
||||
if (url.includes('login')) {
|
||||
console.log('Already on login page, skipping authentication');
|
||||
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();
|
||||
} catch (e) {
|
||||
console.error('Error during authentication:', e);
|
||||
}
|
||||
|
||||
try {
|
||||
await page.context().storageState({ path: authStateFile });
|
||||
} catch (e) {
|
||||
console.error('Error saving authentication state:', e);
|
||||
}
|
||||
});
|
||||
11
frontend/tests/playwright/dashboards.spec.ts
Normal file
11
frontend/tests/playwright/dashboards.spec.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('Check if dashboards exist', async ({ page }) => {
|
||||
await page.goto('http://localhost:3333/login');
|
||||
await page.locator('[data-test-id="login"]').fill('andrei@openreplay.com');
|
||||
await page.locator('[data-test-id="password"]').fill('Andrey123!');
|
||||
await page.locator('[data-test-id="log-button"]').click();
|
||||
await page.getByText('Dashboards').click();
|
||||
await page.getByText('Renamed One').click();
|
||||
await expect(page.getByRole('heading', { name: 'Renamed One' })).toBeVisible();
|
||||
});
|
||||
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 = 'tests/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 });
|
||||
})
|
||||
}
|
||||
16
frontend/tests/playwright/sessionList.spec.ts
Normal file
16
frontend/tests/playwright/sessionList.spec.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
import { testUseAuthState } from './helpers';
|
||||
|
||||
testUseAuthState();
|
||||
|
||||
test('check session list after change period', async ({ page }) => {
|
||||
await page.goto('http://localhost:3333/login');
|
||||
await page.locator('[data-test-id="login"]').fill('andrei@openreplay.com');
|
||||
await page.locator('[data-test-id="password"]').fill('Andrey123!');
|
||||
await page.locator('[data-test-id="log-button"]').click();
|
||||
await page.getByRole('button', { name: 'Android caret-down' }).click();
|
||||
await page.getByRole('menuitem', { name: 'OpenReplay Documentation Site' }).click();
|
||||
await page.getByRole('button', { name: 'Past 24 Hours down' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Past 30 Days' }).click();
|
||||
await page.locator('#session-item').first().click();
|
||||
});
|
||||
9
frontend/tests/playwright/sign-in.spec.ts
Normal file
9
frontend/tests/playwright/sign-in.spec.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('Sign in flow', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.locator('[data-test-id="login"]').fill('andrei@openreplay.com');
|
||||
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();
|
||||
});
|
||||
14
frontend/tests/playwright/spots.spec.ts
Normal file
14
frontend/tests/playwright/spots.spec.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('Spots should display', async ({ page }) => {
|
||||
await page.goto('http://localhost:3333/login');
|
||||
await page.locator('[data-test-id="login"]').fill('andrei@openreplay.com');
|
||||
await page.locator('[data-test-id="password"]').fill('Andrey123!');
|
||||
await page.locator('[data-test-id="log-button"]').click();
|
||||
await page.getByText('Spots').click();
|
||||
await page.waitForTimeout(1000);
|
||||
const spotItems = (
|
||||
await page.locator('[data-test-id="spot-list-item"]').all()
|
||||
).length;
|
||||
expect(spotItems).toBeGreaterThan(0);
|
||||
});
|
||||
37
frontend/tests/playwright/whitescreen.spec.ts
Normal file
37
frontend/tests/playwright/whitescreen.spec.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('The freshest session from openreplay website doesnt have white screen', async ({ page }) => {
|
||||
await page.goto('http://localhost:3333/login');
|
||||
await page.locator('[data-test-id="login"]').fill('andrei@openreplay.com');
|
||||
await page.locator('[data-test-id="password"]').fill('Andrey123!');
|
||||
await page.locator('[data-test-id="log-button"]').click();
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('[data-test-id="session-list-header"]').locator('[data-test-id="widget-select-date-range"]').click();
|
||||
await page.getByText('Past 30 Days').click();
|
||||
await page.locator('[data-test-id="project-dropdown"]').click();
|
||||
await page.getByRole('button', { name: 'Android caret-down' }).click();
|
||||
await page.getByText('OpenReplay Documentation Site').click();
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
const borderBlocks = await page.locator('.border-b').elementHandles();
|
||||
if (borderBlocks.length >= 2) {
|
||||
const secondBlock = borderBlocks[1];
|
||||
const playButton = await secondBlock.$('#play-button');
|
||||
|
||||
if (playButton) {
|
||||
const link = await playButton.$('a');
|
||||
if (link) {
|
||||
await link.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
const iframeElement = await page
|
||||
.locator('iframe[class^="screen-module__iframe"]')
|
||||
.first();
|
||||
const frameHandle = await iframeElement.elementHandle();
|
||||
const frame = await frameHandle?.contentFrame();
|
||||
const hasBody = await frame?.evaluate(() => !!document.body);
|
||||
expect(hasBody).toBeTruthy();
|
||||
});
|
||||
|
|
@ -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', () => {
|
||||
|
|
@ -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');
|
||||
});
|
||||
|
||||
|
|
@ -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,10 +153,16 @@ 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"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2900,6 +2900,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"
|
||||
|
|
@ -8680,6 +8691,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"
|
||||
|
|
@ -8690,6 +8711,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"
|
||||
|
|
@ -12897,6 +12927,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"
|
||||
|
|
@ -12969,6 +13000,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"
|
||||
|
|
@ -13428,6 +13460,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"
|
||||
|
|
|
|||
66
tests/playwright/auth-state.json
Normal file
66
tests/playwright/auth-state.json
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
{
|
||||
"cookies": [],
|
||||
"origins": [
|
||||
{
|
||||
"origin": "http://localhost:3333",
|
||||
"localStorage": [
|
||||
{
|
||||
"name": "__$session-timezone$_local__",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "i18nextLng",
|
||||
"value": "en"
|
||||
},
|
||||
{
|
||||
"name": "theme",
|
||||
"value": "light"
|
||||
},
|
||||
{
|
||||
"name": "__$user-gettingStarted$__",
|
||||
"value": "{\"steps\":[{\"title\":\"🛠️ Install OpenReplay\",\"status\":\"completed\"},{\"title\":\"🕵️ Identify Users\",\"status\":\"completed\"},{\"title\":\"🧑💻 Invite Team Members\",\"status\":\"completed\"},{\"title\":\"🔌 Integrations\",\"status\":\"completed\"}],\"status\":\"completed\"}"
|
||||
},
|
||||
{
|
||||
"name": "___$or_spotToken$___",
|
||||
"value": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjU4LCJ0ZW5hbnRJZCI6MSwiZXhwIjoxNzQ4OTQ1MTQxLCJpc3MiOiJPcGVuUmVwbGF5LW9zcyIsImlhdCI6MTc0ODk0NDU0MSwiYXVkIjoic3BvdDpPcGVuUmVwbGF5In0._QEHvIc8ShH0PsRPtDQAo50Dc-H-Adpu8CZKXQsPF31GSLUl5SS9MV92xntRxfcloigRA1Hz2F817EF5jrgNJg"
|
||||
},
|
||||
{
|
||||
"name": "__$session-timezone$__",
|
||||
"value": "{\"label\":\"UTC +02:00\",\"value\":\"UTC+02\"}"
|
||||
},
|
||||
{
|
||||
"name": "__$session-mouseTrail$__",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "__openreplay_health_status",
|
||||
"value": "1748944551307"
|
||||
},
|
||||
{
|
||||
"name": "__$user-siteId$__",
|
||||
"value": "65"
|
||||
},
|
||||
{
|
||||
"name": "__or__langBannerClosed",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": "AuthStore",
|
||||
"value": "{\"authDetails\":\"{\\\"tenants\\\":true,\\\"sso\\\":null,\\\"ssoProvider\\\":null,\\\"enforceSSO\\\":null,\\\"edition\\\":\\\"foss\\\"}\",\"__mps__\":{\"expireInTimestamp\":1748948149584}}"
|
||||
},
|
||||
{
|
||||
"name": "UserStore",
|
||||
"value": "{\"siteId\":null,\"tenants\":[],\"jwt\":\"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjU4LCJ0ZW5hbnRJZCI6MSwiZXhwIjoxNzQ5MDMwOTQxLCJpc3MiOiJPcGVuUmVwbGF5LW9zcyIsImlhdCI6MTc0ODk0NDU0MSwiYXVkIjoiZnJvbnQ6T3BlblJlcGxheSJ9.YHb2kldXFPzP2ecGoyPOo6I7_KH0BqhimOQKa1VtvSe_LTf2AzQNvKAYmsnx6-55lWX_b4wV5g4s4cdsYexOdw\",\"spotJwt\":\"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjU4LCJ0ZW5hbnRJZCI6MSwiZXhwIjoxNzQ4OTQ1MTQxLCJpc3MiOiJPcGVuUmVwbGF5LW9zcyIsImlhdCI6MTc0ODk0NDU0MSwiYXVkIjoic3BvdDpPcGVuUmVwbGF5In0._QEHvIc8ShH0PsRPtDQAo50Dc-H-Adpu8CZKXQsPF31GSLUl5SS9MV92xntRxfcloigRA1Hz2F817EF5jrgNJg\",\"scopeState\":2,\"onboarding\":false,\"account\":\"{\\\"id\\\":58,\\\"email\\\":\\\"andrei@openreplay.com\\\",\\\"smtp\\\":false,\\\"expirationDate\\\":-1,\\\"permissions\\\":[],\\\"settings\\\":{\\\"modules\\\":[\\\"usability-tests\\\",\\\"feature-flags\\\"]},\\\"iceServers\\\":[],\\\"hasPassword\\\":true,\\\"apiKey\\\":\\\"48Vph82zUEWHmfPSUbgG\\\",\\\"edition\\\":\\\"foss\\\",\\\"optOut\\\":false,\\\"versionNumber\\\":\\\"1.17.0\\\",\\\"name\\\":\\\"Andrei\\\",\\\"createdAt\\\":1652690354756,\\\"admin\\\":true,\\\"superAdmin\\\":false}\"}"
|
||||
},
|
||||
{
|
||||
"name": "__openreplay_health_response",
|
||||
"value": "{\"overallHealth\":true,\"healthMap\":{\"databases\":{\"name\":\"Databases\",\"healthOk\":true,\"subservices\":{\"postgres\":{\"health\":true,\"details\":{}}},\"serviceName\":\"databases\"},\"ingestionPipeline\":{\"name\":\"Ingestion Pipeline\",\"healthOk\":true,\"subservices\":{\"redis\":{\"health\":true,\"details\":{}}},\"serviceName\":\"ingestionPipeline\"},\"backendServices\":{\"name\":\"Backend Services\",\"healthOk\":true,\"subservices\":{\"alerts\":{\"health\":true,\"details\":{}},\"assets\":{\"health\":true,\"details\":{}},\"assist\":{\"health\":true,\"details\":{}},\"chalice\":{\"health\":true,\"details\":{}},\"db\":{\"health\":true,\"details\":{}},\"ender\":{\"health\":true,\"details\":{}},\"frontend\":{\"health\":true,\"details\":{}},\"heuristics\":{\"health\":true,\"details\":{}},\"http\":{\"health\":true,\"details\":{}},\"ingress-nginx\":{\"health\":true,\"details\":{}},\"integrations\":{\"health\":true,\"details\":{}},\"sink\":{\"health\":true,\"details\":{}},\"sourcemapreader\":{\"health\":true,\"details\":{}},\"storage\":{\"health\":true,\"details\":{}}},\"serviceName\":\"backendServices\"}},\"details\":{\"numberOfSessionsCaptured\":216813,\"numberOfEventCaptured\":1841202}}"
|
||||
},
|
||||
{
|
||||
"name": "__$session-filter$__",
|
||||
"value": "{\"name\":\"\",\"events\":[],\"custom\":{},\"rangeValue\":\"LAST_30_DAYS\",\"startDate\":1746352800000,\"endDate\":1748944800000,\"groupByUser\":false,\"sort\":\"startTs\",\"order\":\"desc\",\"strict\":false,\"eventsOrder\":\"then\",\"limit\":10,\"rangeName\":\"LAST_30_DAYS\",\"page\":1,\"perPage\":10,\"tab\":\"sessions\",\"filters\":[{\"type\":\"location\",\"isEvent\":true,\"value\":[\"\"],\"operator\":\"isAny\",\"source\":\"\",\"sourceOperator\":\"\",\"filters\":[]}]}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue