add ai functions
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Some checks reported errors
continuous-integration/drone/push Build encountered an error
This commit is contained in:
463
tests/e2e/phase3.spec.ts
Normal file
463
tests/e2e/phase3.spec.ts
Normal file
@ -0,0 +1,463 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* E2E тесты для Фазы 3 Team Planner
|
||||
* - AI-оценка трудозатрат
|
||||
*
|
||||
* Используем data-testid для стабильных селекторов
|
||||
*/
|
||||
|
||||
test.describe('Фаза 3: AI-оценка', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForSelector('[data-testid="ideas-table"]', { timeout: 10000 });
|
||||
});
|
||||
|
||||
test('Кнопка AI-оценки присутствует в каждой строке', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
if (hasData) {
|
||||
const estimateButtons = page.locator('[data-testid="estimate-idea-button"]');
|
||||
const buttonCount = await estimateButtons.count();
|
||||
expect(buttonCount).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
|
||||
test('Клик на кнопку AI-оценки открывает модалку', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
// Кликаем на кнопку AI-оценки первой идеи
|
||||
const estimateButton = page.locator('[data-testid="estimate-idea-button"]').first();
|
||||
await estimateButton.click();
|
||||
|
||||
// Проверяем что модалка открылась
|
||||
const modal = page.locator('[data-testid="ai-estimate-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
test('Модалка AI-оценки показывает загрузку', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
const estimateButton = page.locator('[data-testid="estimate-idea-button"]').first();
|
||||
await estimateButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="ai-estimate-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Должен быть либо индикатор загрузки, либо результат, либо ошибка
|
||||
const hasContent = await modal.locator('text=Анализируем').isVisible().catch(() => false) ||
|
||||
await modal.locator('text=Общее время').isVisible().catch(() => false) ||
|
||||
await modal.locator('text=Не удалось').isVisible().catch(() => false);
|
||||
|
||||
expect(hasContent).toBeTruthy();
|
||||
});
|
||||
|
||||
test('AI-оценка возвращает результат с часами и сложностью', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
const estimateButton = page.locator('[data-testid="estimate-idea-button"]').first();
|
||||
await estimateButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="ai-estimate-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Ждём результат (до 30 секунд - AI может отвечать долго)
|
||||
const totalTimeLabel = modal.locator('text=Общее время');
|
||||
await expect(totalTimeLabel).toBeVisible({ timeout: 30000 });
|
||||
|
||||
// Проверяем наличие сложности
|
||||
const complexityLabel = modal.locator('text=Сложность');
|
||||
await expect(complexityLabel).toBeVisible();
|
||||
});
|
||||
|
||||
test('AI-оценка показывает разбивку по ролям', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
const estimateButton = page.locator('[data-testid="estimate-idea-button"]').first();
|
||||
await estimateButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="ai-estimate-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Ждём результат
|
||||
await expect(modal.locator('text=Общее время')).toBeVisible({ timeout: 30000 });
|
||||
|
||||
// Проверяем наличие таблицы разбивки по ролям
|
||||
const breakdownLabel = modal.locator('text=Разбивка по ролям');
|
||||
// Разбивка опциональна (может не быть если команда не указана)
|
||||
const hasBreakdown = await breakdownLabel.isVisible().catch(() => false);
|
||||
|
||||
if (hasBreakdown) {
|
||||
const breakdownRows = modal.locator('[data-testid^="estimate-breakdown-row-"]');
|
||||
const rowCount = await breakdownRows.count();
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
}
|
||||
});
|
||||
|
||||
test('Кнопка закрытия модалки работает', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
const estimateButton = page.locator('[data-testid="estimate-idea-button"]').first();
|
||||
await estimateButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="ai-estimate-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Закрываем модалку
|
||||
const closeButton = page.locator('[data-testid="close-estimate-modal-button"]');
|
||||
await closeButton.click();
|
||||
|
||||
// Модалка должна закрыться
|
||||
await expect(modal).not.toBeVisible({ timeout: 3000 });
|
||||
});
|
||||
|
||||
test('После оценки результат сохраняется в строке таблицы', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
// Запоминаем первую строку
|
||||
const firstRow = page.locator('[data-testid^="idea-row-"]').first();
|
||||
|
||||
// Кликаем на оценку
|
||||
const estimateButton = firstRow.locator('[data-testid="estimate-idea-button"]');
|
||||
await estimateButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="ai-estimate-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Ждём результат
|
||||
await expect(modal.locator('text=Общее время')).toBeVisible({ timeout: 30000 });
|
||||
|
||||
// Закрываем модалку
|
||||
await page.locator('[data-testid="close-estimate-modal-button"]').click();
|
||||
await expect(modal).not.toBeVisible({ timeout: 3000 });
|
||||
|
||||
// Проверяем что в строке появилась оценка (часы или дни)
|
||||
// Ищем текст типа "8ч" или "2д" в строке
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Колонка "Оценка" должна содержать данные
|
||||
const rowText = await firstRow.textContent();
|
||||
const hasEstimate = rowText?.match(/\d+[чд]/) !== null;
|
||||
|
||||
expect(hasEstimate).toBeTruthy();
|
||||
});
|
||||
|
||||
test('Колонка "Оценка" отображается в таблице', async ({ page }) => {
|
||||
const table = page.locator('[data-testid="ideas-table"]');
|
||||
await expect(table).toBeVisible();
|
||||
|
||||
// Проверяем наличие заголовка колонки
|
||||
const header = table.locator('th', { hasText: 'Оценка' });
|
||||
await expect(header).toBeVisible();
|
||||
});
|
||||
|
||||
test('Клик по оценке открывает модалку с деталями', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
// Ищем строку с оценкой (кнопка view-estimate-button появляется только если есть оценка)
|
||||
const viewEstimateButton = page.locator('[data-testid="view-estimate-button"]').first();
|
||||
const hasEstimate = await viewEstimateButton.isVisible().catch(() => false);
|
||||
|
||||
test.skip(!hasEstimate, 'Нет идей с оценкой для тестирования');
|
||||
|
||||
// Кликаем по оценке
|
||||
await viewEstimateButton.click();
|
||||
|
||||
// Модалка должна открыться с деталями
|
||||
const modal = page.locator('[data-testid="ai-estimate-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Должны быть видны результаты (без загрузки)
|
||||
await expect(modal.locator('text=Общее время')).toBeVisible();
|
||||
await expect(modal.locator('text=Сложность')).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Фаза 3: AI-оценка - создание данных для теста', () => {
|
||||
test('Создание идеи и запуск AI-оценки', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForSelector('[data-testid="ideas-table"]', { timeout: 10000 });
|
||||
|
||||
// Проверяем есть ли кнопка создания идеи
|
||||
const createButton = page.locator('[data-testid="create-idea-button"]');
|
||||
const hasCreateButton = await createButton.isVisible().catch(() => false);
|
||||
|
||||
if (hasCreateButton) {
|
||||
// Создаём идею
|
||||
await createButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="create-idea-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Заполняем форму
|
||||
await page.locator('[data-testid="idea-title-input"] input').fill('Тестовая идея для AI-оценки');
|
||||
await page.locator('[data-testid="idea-description-input"] textarea').first().fill(
|
||||
'Реализовать систему уведомлений. Нужны email и push-уведомления для важных событий.'
|
||||
);
|
||||
|
||||
// Сохраняем
|
||||
await page.locator('[data-testid="submit-create-idea"]').click();
|
||||
await expect(modal).not.toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Ждём появления новой строки
|
||||
await page.waitForTimeout(1000);
|
||||
}
|
||||
|
||||
// Теперь проверяем AI-оценку
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Не удалось создать данные для тестирования');
|
||||
|
||||
// Запускаем AI-оценку
|
||||
const estimateButton = page.locator('[data-testid="estimate-idea-button"]').first();
|
||||
await estimateButton.click();
|
||||
|
||||
const estimateModal = page.locator('[data-testid="ai-estimate-modal"]');
|
||||
await expect(estimateModal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Ждём результат (до 60 секунд - AI может отвечать долго)
|
||||
// Или ошибку (текст "Не удалось" из компонента)
|
||||
const resultOrError = estimateModal.locator('text=/Общее время|Не удалось/');
|
||||
await expect(resultOrError).toBeVisible({ timeout: 60000 });
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Тесты для генерации мини-ТЗ (Phase 3.1)
|
||||
*/
|
||||
test.describe('Фаза 3.1: Генерация мини-ТЗ', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForSelector('[data-testid="ideas-table"]', { timeout: 10000 });
|
||||
});
|
||||
|
||||
test('Кнопка ТЗ присутствует в каждой строке', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
if (hasData) {
|
||||
const specButtons = page.locator('[data-testid="specification-button"]');
|
||||
const buttonCount = await specButtons.count();
|
||||
expect(buttonCount).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
|
||||
test('Клик на кнопку ТЗ открывает модалку', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
// Кликаем на кнопку ТЗ первой идеи
|
||||
const specButton = page.locator('[data-testid="specification-button"]').first();
|
||||
await specButton.click();
|
||||
|
||||
// Проверяем что модалка открылась
|
||||
const modal = page.locator('[data-testid="specification-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
test('Модалка ТЗ показывает загрузку при генерации', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
// Ищем строку без ТЗ (кнопка не подсвечена синим)
|
||||
const specButton = page.locator('[data-testid="specification-button"]').first();
|
||||
await specButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="specification-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Должен быть либо индикатор загрузки, либо контент, либо ошибка
|
||||
const hasContent = await modal.locator('[data-testid="specification-loading"]').isVisible().catch(() => false) ||
|
||||
await modal.locator('[data-testid="specification-content"]').isVisible().catch(() => false) ||
|
||||
await modal.locator('[data-testid="specification-error"]').isVisible().catch(() => false);
|
||||
|
||||
expect(hasContent).toBeTruthy();
|
||||
});
|
||||
|
||||
test('Генерация ТЗ возвращает результат', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
const specButton = page.locator('[data-testid="specification-button"]').first();
|
||||
await specButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="specification-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Ждём результат (до 60 секунд - AI может отвечать долго)
|
||||
const content = modal.locator('[data-testid="specification-content"]');
|
||||
const error = modal.locator('[data-testid="specification-error"]');
|
||||
|
||||
// Ожидаем либо контент, либо ошибку
|
||||
await expect(content.or(error)).toBeVisible({ timeout: 60000 });
|
||||
});
|
||||
|
||||
test('Кнопка закрытия модалки ТЗ работает', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
const specButton = page.locator('[data-testid="specification-button"]').first();
|
||||
await specButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="specification-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Ждём пока загрузится контент или ошибка
|
||||
const content = modal.locator('[data-testid="specification-content"]');
|
||||
const error = modal.locator('[data-testid="specification-error"]');
|
||||
await expect(content.or(error)).toBeVisible({ timeout: 60000 });
|
||||
|
||||
// Закрываем модалку
|
||||
const closeButton = page.locator('[data-testid="specification-close-button"]');
|
||||
await closeButton.click();
|
||||
|
||||
// Модалка должна закрыться
|
||||
await expect(modal).not.toBeVisible({ timeout: 3000 });
|
||||
});
|
||||
|
||||
test('Кнопка редактирования ТЗ появляется после генерации', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
const specButton = page.locator('[data-testid="specification-button"]').first();
|
||||
await specButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="specification-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Ждём контент
|
||||
const content = modal.locator('[data-testid="specification-content"]');
|
||||
const hasContent = await content.isVisible({ timeout: 60000 }).catch(() => false);
|
||||
|
||||
if (hasContent) {
|
||||
// Проверяем наличие кнопки редактирования
|
||||
const editButton = modal.locator('[data-testid="specification-edit-button"]');
|
||||
await expect(editButton).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('Редактирование ТЗ открывает textarea', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
const specButton = page.locator('[data-testid="specification-button"]').first();
|
||||
await specButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="specification-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Ждём контент
|
||||
const content = modal.locator('[data-testid="specification-content"]');
|
||||
const hasContent = await content.isVisible({ timeout: 60000 }).catch(() => false);
|
||||
|
||||
test.skip(!hasContent, 'Не удалось сгенерировать ТЗ');
|
||||
|
||||
// Кликаем редактировать
|
||||
const editButton = modal.locator('[data-testid="specification-edit-button"]');
|
||||
await editButton.click();
|
||||
|
||||
// Должен появиться textarea
|
||||
const textarea = modal.locator('[data-testid="specification-textarea"]');
|
||||
await expect(textarea).toBeVisible();
|
||||
});
|
||||
|
||||
test('Сохранение отредактированного ТЗ', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
const specButton = page.locator('[data-testid="specification-button"]').first();
|
||||
await specButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="specification-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Ждём контент
|
||||
const content = modal.locator('[data-testid="specification-content"]');
|
||||
const hasContent = await content.isVisible({ timeout: 60000 }).catch(() => false);
|
||||
|
||||
test.skip(!hasContent, 'Не удалось сгенерировать ТЗ');
|
||||
|
||||
// Кликаем редактировать
|
||||
const editButton = modal.locator('[data-testid="specification-edit-button"]');
|
||||
await editButton.click();
|
||||
|
||||
// Редактируем текст
|
||||
const textarea = modal.locator('[data-testid="specification-textarea"] textarea');
|
||||
const testText = '\n\n## Дополнительно\nТестовая правка ' + Date.now();
|
||||
await textarea.fill(await textarea.inputValue() + testText);
|
||||
|
||||
// Сохраняем
|
||||
const saveButton = modal.locator('[data-testid="specification-save-button"]');
|
||||
await saveButton.click();
|
||||
|
||||
// Должен вернуться режим просмотра
|
||||
await expect(content).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Проверяем что изменения сохранились
|
||||
const contentText = await content.textContent();
|
||||
expect(contentText).toContain('Дополнительно');
|
||||
});
|
||||
|
||||
test('Повторное открытие показывает сохранённое ТЗ', async ({ page }) => {
|
||||
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
|
||||
const hasData = !(await emptyState.isVisible().catch(() => false));
|
||||
|
||||
test.skip(!hasData, 'Нет данных для тестирования');
|
||||
|
||||
// Ищем идею с уже сгенерированным ТЗ (кнопка синяя)
|
||||
const blueSpecButton = page.locator('[data-testid="specification-button"][class*="primary"]').first();
|
||||
const hasExistingSpec = await blueSpecButton.isVisible().catch(() => false);
|
||||
|
||||
test.skip(!hasExistingSpec, 'Нет идей с ТЗ для тестирования');
|
||||
|
||||
await blueSpecButton.click();
|
||||
|
||||
const modal = page.locator('[data-testid="specification-modal"]');
|
||||
await expect(modal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Контент должен появиться сразу (без загрузки)
|
||||
const content = modal.locator('[data-testid="specification-content"]');
|
||||
await expect(content).toBeVisible({ timeout: 3000 });
|
||||
|
||||
// Не должно быть индикатора загрузки
|
||||
const loading = modal.locator('[data-testid="specification-loading"]');
|
||||
await expect(loading).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
@ -2,7 +2,7 @@
|
||||
"cookies": [
|
||||
{
|
||||
"name": "AUTH_SESSION_ID",
|
||||
"value": "aDcxV2VydUZQUVNSUHM0S290YzZtdVV2LlJBd2xHOXUyNWh6a1o2Qkc0V3pxRkpkNng5MVkza2o2REE0eTYyN21jWTJ6TS1WbC01Yk16UWZjZFRHcFNjWDRpMWJNTlhQZUZkZ3MxeW9WcHd4dnBn.keycloak-keycloakx-0-40655",
|
||||
"value": "c2hWNkNfa0JhY1hOc1ZWTnhLdk1tOTllLnNBM2ZQTk5yRlBKek5lS3FoR093OFloU1ZyU3E1QzFadzVIU1Jta2lMRllqbXJxLW9QSEMxOFkzZWZDZDl3UHVKZUVaU0VvWWJTOVRNTHJJSUpZc1hB.keycloak-keycloakx-0-40655",
|
||||
"domain": "auth.vigdorov.ru",
|
||||
"path": "/realms/team-planner/",
|
||||
"expires": -1,
|
||||
@ -12,17 +12,17 @@
|
||||
},
|
||||
{
|
||||
"name": "KC_AUTH_SESSION_HASH",
|
||||
"value": "on0q6coyrWw3ypD0a99QFRAKTjOKY9lwC5JUXEZd+1M",
|
||||
"value": "\"gFqhBG3DVcCfpsSCaidKwK+Ziy23r6ddJ/rdb/jKDs8\"",
|
||||
"domain": "auth.vigdorov.ru",
|
||||
"path": "/realms/team-planner/",
|
||||
"expires": 1768425176.234387,
|
||||
"expires": 1768427781.187379,
|
||||
"httpOnly": false,
|
||||
"secure": true,
|
||||
"sameSite": "None"
|
||||
},
|
||||
{
|
||||
"name": "KEYCLOAK_IDENTITY",
|
||||
"value": "eyJhbGciOiJIUzUxMiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI2ZDRjMWU2My1hNTllLTQ0NjAtYThkYy05YTRiZjFjMTRjMDMifQ.eyJleHAiOjE3Njg0NjExMTcsImlhdCI6MTc2ODQyNTExNywianRpIjoiMjMxZmU5ZmQtM2QzMC1hODE4LWJiZTItNjhjMDRhMTNlMTk1IiwiaXNzIjoiaHR0cHM6Ly9hdXRoLnZpZ2Rvcm92LnJ1L3JlYWxtcy90ZWFtLXBsYW5uZXIiLCJzdWIiOiIyZDJiOTRmMC0xZWQ1LTQ0MTUtYmM4MC1jZTRlZWMxNDQ1NGQiLCJ0eXAiOiJTZXJpYWxpemVkLUlEIiwic2lkIjoiaDcxV2VydUZQUVNSUHM0S290YzZtdVV2Iiwic3RhdGVfY2hlY2tlciI6IjZjSXJIcFBVX09FSnpkNUpWWHRPMUVveS1aaVN1RS1jVGNpQVRyX01WVWsifQ.B4IGHS3mMLHkLMJlfyU8xJK_Xz8wtTeOEtSm57qbKHdnUYdXaavWNdPwIZ1rrPprPiypqn0_Ddj28dQVdNkClQ",
|
||||
"value": "eyJhbGciOiJIUzUxMiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI2ZDRjMWU2My1hNTllLTQ0NjAtYThkYy05YTRiZjFjMTRjMDMifQ.eyJleHAiOjE3Njg0NjM3MjMsImlhdCI6MTc2ODQyNzcyMywianRpIjoiNGRmN2U5MzQtY2Q4Mi1hYTYwLTViNTUtMWFhZjVlMWViODJjIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLnZpZ2Rvcm92LnJ1L3JlYWxtcy90ZWFtLXBsYW5uZXIiLCJzdWIiOiIyZDJiOTRmMC0xZWQ1LTQ0MTUtYmM4MC1jZTRlZWMxNDQ1NGQiLCJ0eXAiOiJTZXJpYWxpemVkLUlEIiwic2lkIjoic2hWNkNfa0JhY1hOc1ZWTnhLdk1tOTllIiwic3RhdGVfY2hlY2tlciI6Im9Ic2R0czlWR0RvV19EcjcxbG4tM2FjWDR1SmJuMWtzdHRCcVpzRnlPbDQifQ.Nbi8YdiZddWqY4rsS7b_hin9cbTedp2bOQ11I25tLdTH6VGGJaCP1T59pYd3OlqyDYPoD97uOBiobKTues1rwg",
|
||||
"domain": "auth.vigdorov.ru",
|
||||
"path": "/realms/team-planner/",
|
||||
"expires": -1,
|
||||
@ -32,10 +32,10 @@
|
||||
},
|
||||
{
|
||||
"name": "KEYCLOAK_SESSION",
|
||||
"value": "on0q6coyrWw3ypD0a99QFRAKTjOKY9lwC5JUXEZd-1M",
|
||||
"value": "gFqhBG3DVcCfpsSCaidKwK-Ziy23r6ddJ_rdb_jKDs8",
|
||||
"domain": "auth.vigdorov.ru",
|
||||
"path": "/realms/team-planner/",
|
||||
"expires": 1768461118.031888,
|
||||
"expires": 1768463723.271756,
|
||||
"httpOnly": false,
|
||||
"secure": true,
|
||||
"sameSite": "None"
|
||||
|
||||
Reference in New Issue
Block a user