mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-19 09:09:41 +03:00
docs(web-test): BrowserContext вместо sequential reconnect для мульти-контекста
Один процесс браузера, несколько изолированных BrowserContext'ов. Мгновенное переключение между пользователями, состояние каждой сессии сохраняется. Не требует полного рефакторинга createContext(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,9 +46,10 @@ In-process (не через HTTP). Раннер:
|
||||
3. Импортирует каждый модуль, извлекает метаданные
|
||||
4. Фильтрует по тегам/grep/only
|
||||
5. Группирует по контексту, сортирует по алфавиту внутри группы
|
||||
6. Подключается к 1С (`browser.connect(url)`)
|
||||
7. Выполняет тесты последовательно
|
||||
8. Отключается, выводит результаты
|
||||
6. Запускает браузер (`chromium.launch()`)
|
||||
7. Создаёт BrowserContext + page для каждого используемого контекста (лениво)
|
||||
8. Выполняет тесты последовательно, переключая активный контекст
|
||||
9. Закрывает все контексты и браузер, выводит результаты
|
||||
|
||||
---
|
||||
|
||||
@@ -280,19 +281,21 @@ assert.noErrors(state, msg)
|
||||
### Порядок выполнения
|
||||
|
||||
```
|
||||
prepare() // без браузера
|
||||
browser.connect(url)
|
||||
beforeAll(ctx) // браузер готов
|
||||
prepare() // без браузера (восстановление БД, публикация)
|
||||
browser.launch() // запуск процесса браузера
|
||||
создание BrowserContext'ов // по одному на каждый используемый контекст
|
||||
beforeAll(ctx) // браузер готов, контексты созданы
|
||||
beforeEach(ctx)
|
||||
test.setup(ctx) // подготовка теста
|
||||
test.default(ctx) // тело теста
|
||||
test.teardown(ctx) // очистка теста (всегда)
|
||||
afterEach(ctx) // всегда
|
||||
[встроенный сброс] // всегда
|
||||
test.setup(ctx) // подготовка теста
|
||||
test.default(ctx) // тело теста
|
||||
test.teardown(ctx) // очистка теста (всегда)
|
||||
afterEach(ctx) // всегда
|
||||
[встроенный сброс] // всегда (для каждого активного контекста)
|
||||
...следующий тест...
|
||||
afterAll(ctx)
|
||||
browser.disconnect()
|
||||
cleanup() // без браузера
|
||||
закрытие всех BrowserContext'ов
|
||||
browser.close()
|
||||
cleanup() // без браузера (удаление публикации)
|
||||
```
|
||||
|
||||
### Встроенный сброс состояния
|
||||
@@ -372,9 +375,30 @@ export default {
|
||||
|
||||
## 8. Контексты
|
||||
|
||||
### Механизм: Playwright BrowserContext
|
||||
|
||||
Один процесс браузера (`chromium.launch()`), несколько изолированных контекстов.
|
||||
Каждый контекст -- отдельная сессия (куки, авторизация, состояние страницы).
|
||||
|
||||
```
|
||||
browser (один процесс chromium)
|
||||
├─ BrowserContext "кладовщик" → page → http://localhost/app-clerk/ru_RU
|
||||
├─ BrowserContext "менеджер" → page → http://localhost/app-mgr/ru_RU
|
||||
└─ BrowserContext "админ" → page → http://localhost/app-admin/ru_RU
|
||||
```
|
||||
|
||||
Преимущества:
|
||||
- **Мгновенное переключение** между пользователями (смена активного `page`)
|
||||
- **Состояние сохраняется** -- переключились на менеджера и обратно, у кладовщика
|
||||
все формы остались открытыми, ничего не потеряно
|
||||
- **Нет переподключений** -- каждая сессия живёт независимо
|
||||
- **Один процесс** -- экономия ресурсов по сравнению с несколькими браузерами
|
||||
- **Стандартный паттерн** Playwright для мульти-пользовательских сценариев
|
||||
|
||||
### Одиночный контекст (по умолчанию)
|
||||
|
||||
Большинство тестов. Один браузер, один пользователь. Тест получает плоский контекст со всем API.
|
||||
Большинство тестов. Один BrowserContext, один пользователь.
|
||||
Тест получает плоский контекст со всем API.
|
||||
|
||||
```js
|
||||
export const context = 'кладовщик'; // необязательно, используется defaultContext
|
||||
@@ -383,10 +407,13 @@ export default async function({ clickElement, fillFields, ... }) { }
|
||||
|
||||
### Группировка по контексту
|
||||
|
||||
Раннер группирует тесты по значению `context`, минимизирует переподключения:
|
||||
1. Собрать все тесты, сгруппировать по имени контекста
|
||||
2. Для каждой группы: подключиться -> выполнить тесты -> отключиться
|
||||
3. Внутри группы тесты выполняются по алфавиту
|
||||
Раннер группирует тесты по значению `context`:
|
||||
1. Собрать все тесты, определить набор уникальных контекстов
|
||||
2. Создать BrowserContext + page для каждого используемого контекста
|
||||
3. Для каждой группы тестов: переключить активный context, выполнить тесты
|
||||
4. Внутри группы тесты выполняются по алфавиту
|
||||
|
||||
Контексты создаются лениво (при первом обращении) и живут до конца прогона.
|
||||
|
||||
### Мульти-контекст (процессные тесты)
|
||||
|
||||
@@ -395,11 +422,43 @@ export const contexts = ['кладовщик', 'менеджер'];
|
||||
export default async function({ кладовщик, менеджер, step, assert }) { }
|
||||
```
|
||||
|
||||
Каждый именованный контекст -- полноценный объект API. Тест оркестрирует переключение.
|
||||
Каждый именованный контекст -- полноценный объект API со своим `page`.
|
||||
Тест оркестрирует переключение между пользователями.
|
||||
Состояние каждого пользователя сохраняется между переключениями:
|
||||
|
||||
**Этапы реализации:**
|
||||
- Этап 1: последовательное переподключение (отключиться от одного URL, подключиться к другому)
|
||||
- Этап 2: параллельные браузеры (после рефакторинга browser.mjs в `createContext()`)
|
||||
```js
|
||||
await step('Кладовщик создаёт документ', async () => {
|
||||
await кладовщик.openCommand('Приходные накладные');
|
||||
await кладовщик.clickElement('Создать');
|
||||
await кладовщик.fillFields({ 'Контрагент': 'ООО Поставщик' });
|
||||
await кладовщик.clickElement('Записать');
|
||||
// кладовщик стоит на форме документа
|
||||
});
|
||||
|
||||
await step('Менеджер утверждает', async () => {
|
||||
await менеджер.navigateSection('Согласование');
|
||||
await менеджер.clickElement('Утвердить');
|
||||
});
|
||||
|
||||
await step('Кладовщик проверяет статус', async () => {
|
||||
// страница кладовщика ТА ЖЕ -- форма открыта, навигация не нужна
|
||||
const state = await кладовщик.getFormState();
|
||||
assert.equal(state.fields['Статус']?.value, 'Утверждён');
|
||||
});
|
||||
```
|
||||
|
||||
### Влияние на browser.mjs
|
||||
|
||||
Текущий browser.mjs хранит `page`, `browser`, `session` как module-level переменные.
|
||||
Для мульти-контекста необходимо:
|
||||
- Уметь создавать несколько `BrowserContext` + `page` в одном `browser`
|
||||
- Хранить карту контекстов `{ name → { context, page, session } }`
|
||||
- Переключать текущий `page` при смене активного контекста
|
||||
- API-функции раб��тают с текущим активным `page`
|
||||
|
||||
Это промежуточный шаг к полному `createContext()` из Фазы 3 роадмапа,
|
||||
но значительно проще -- не требует рефакторинга всех функций browser.mjs,
|
||||
только управление текущим page.
|
||||
|
||||
---
|
||||
|
||||
@@ -723,7 +782,7 @@ function buildContext({ noRecord = false } = {}) -> object
|
||||
| 3 | Ядро cmdTest() | run.mjs: обнаружение, импорт, выполнение, консольный вывод, JSON-отчёт | #2 |
|
||||
| 4 | Утверждения + обёртка step() | run.mjs: assert.*, step(name, fn) | #3 |
|
||||
| 5 | Хуки (prepare/cleanup + before/after) | run.mjs: поддержка _hooks.mjs | #3 |
|
||||
| 6 | Файл конфигурации + контексты | run.mjs: webtest.config.mjs, маршрутизация контекстов | #3 |
|
||||
| 6 | Файл конфигурации + контексты | run.mjs: webtest.config.mjs, BrowserContext'ы, маршрутизация | #3 |
|
||||
| 7 | Форматы отчётов (Allure, JUnit) | run.mjs: --format=allure/junit | #3 |
|
||||
| 8 | Синтетическая конфигурация | integration/build-webtest-config.test.mjs | спека |
|
||||
| 9 | Smoke-тесты (01-06) | tests/web-test/01-06*.test.mjs | #3, #8 |
|
||||
|
||||
Reference in New Issue
Block a user