Свой помеченный клиент предоставляет реальные окна, группы и кнопки командного интерфейса. Менеджер открывает только собственную форму по настоящей ссылке команды, проверяет сообщение своего сеанса, закрывает лишь панельБ и отдельно восстанавливает лимит, legacy-заголовки и соединение.
Где и как запускать
Полный модуль управляемой формы МенеджерУчебныхОкон85.Пульт: UI выполняется в своём тонком /TESTMANAGER-клиенте8.5.1.1343, имя своей конфигурации читается отдельной серверной функцией без контекста. Собственный тонкий /TESTCLIENT той же новой базы УчебныеОкна85 на вручную проверенном локальном порту15381, Такси.
Подготовка
Создайте с нуля пустую конфигурацию УчебныеОкна85, платформа8.5.1.1343, режим Управляемое приложение, интерфейс Такси. Без прикладных объектов, расширений, подписок, разделителей и рабочей информации. Заголовок или порт сами по себе не доказывают безопасность чужого клиента.
Создайте управляемые общие формы УчебноеОкноА85 и УчебноеОкноБ85. Вставьте их отдельные полные модули ниже. У формыА добавьте строковый реквизит МеткаСеанса и одноимённое поле только для просмотра.
ФормаА: команды ПодготовитьСвойСеанс, ПоказатьСвоеСообщение, ЗавершитьСвойСеанс с одноимёнными клиентскими действиями и кнопками именно с такими внутренними именами. Каждая команда ИзменяетСохраняемыеДанные=Ложь. Назначьте ПриОткрытии и ПередЗакрытием с четырьмя параметрами.
ФормаБ: назначьте ПриОткрытии(Отказ), добавьте текстовую декорацию Это собственная пустая панельБ. Данные не записываются. Заголовки обеих форм задаются модулем, а не автоматически именем конфигурации.
Создайте единственную подсистему УчебныеОкна85 и две общие команды ОткрытьУчебноеОкноА85 и ОткрытьУчебноеОкноБ85. Их синонимы строго Открыть учебное окноА85 и Открыть учебное окноБ85. Вставьте соответствующие полные модули команд ниже; команды без параметра, включены в свою подсистему, доступны и видимы в её командном интерфейсе.
В редакторе командного интерфейса своего раздела разместите две команды в доступной панели действий. Если панель скрыта настройками вашего клиента, сначала покажите её вручную. Тест не разворачивает произвольные группы и не нажимает первые найденные кнопки.
Подготовьте начальную страницу только этой пустой конфигурации: в Рабочую область начальной страницы можно добавить отдельную пустую управляемую общую форму УчебнаяНачальная85. Не назначайте формуА начальной, чтобы не создать две одинаково подписанные формыА. Переходы проверяются только у Основное=Истина.
Обработки → МенеджерУчебныхОкон85 → управляемая форма Пульт. Добавьте реквизиты Согласие типа Булево, МеткаСеанса типа Строка, Порт типа Число(5,0), Итог типа Строка неограниченной длины. Главный код — полный модуль этой формы, а не тестируемой формыА.
В менеджере добавьте команду ВыполнитьСвойТест с одноимённым действием и кнопкой. Назначьте ПриОткрытии(Отказ). Флажок согласия и метка доступны для ручного ввода, Итог только для просмотра. Код не записывает эти значения в базу.
Нажмите F7 и обновите только свою базу. Здесь runtimeVerifiedScenarios=0: реальный клиент, соединение и UI-тест не запускались. Сборка HTML не заменяет проверку в 1С.
Администратор выделяет только свой свободный локальный порт15381 и убеждается, что нет другого клиента на этом порту. Вручную запустите один тонкий клиент этой базы с /TESTCLIENT -TPort15381, другой тонкий клиент той же базы с /TESTMANAGER. Здесь процессы не запускаются.
В тестируемом клиенте вручную откройте формуА командой её раздела, нажмите ПодготовитьСвойСеанс и скопируйте настоящую метку UUID из поля. Не создавайте её в менеджере самостоятельно. Она также входит в заголовок приложения, но это диагностическая проверка владения, не аутентификация.
В менеджере откройте свой Пульт, вставьте фактическую метку, оставьте порт15381 и дайте согласие. В тестируемом клиенте перед тестом не должно быть формыБ или второго экземпляра формыА; основное окно должно оставаться активным.
Рецепт использует старые Установить/ПолучитьЗаголовокКлиентскогоПриложения и Установить/ПолучитьКраткийЗаголовокПриложения специально для изучения legacy-совместимости. С8.3.10 они не рекомендуются; для новой прикладной разработки используйте рекомендованные справкой методы заголовка соответствующего контекста, а не объявляйте старые предпочтительными.
После нормального теста формаБ закрыта, формаА остаётся, прежние действительные заголовки и лимит восстановлены, соединение разорвано. При ошибке восстановления нажмите ЗавершитьСвойСеанс вручную только в своём тестируемом клиенте; не закрывайте чужое приложение.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Согласие = Ложь;
МеткаСеанса = "";
Порт = 15381;
Итог = "Сначала вручную подготовьте только свой клиент тестирования";
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСвойКонтекст()
Если Не Согласие Или Порт <> 15381 Тогда
ВызватьИсключение "Нужно согласие и заранее выделенный свой локальный порт15381";
КонецЕсли;
Если Лев(МеткаСеанса, СтрДлина("УчебныеОкна85-")) <> "УчебныеОкна85-"
Или СтрНайти(МеткаСеанса, "*") > 0 Или СтрНайти(МеткаСеанса, "?") > 0 Тогда
ВызватьИсключение "Скопируйте фактическую метку своего клиента, не шаблон заголовка";
КонецЕсли;
UUIDМетки = Новый УникальныйИдентификатор(Сред(МеткаСеанса, СтрДлина("УчебныеОкна85-") + 1));
Если МеткаСеанса <> "УчебныеОкна85-" + Строка(UUIDМетки) Тогда
ВызватьИсключение "Метка должна содержать точное представление настоящего UUID своего клиента";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСвойКорень(ГлавноеОкно)
Если ТипЗнч(ГлавноеОкно) <> Тип("ТестируемоеОкноКлиентскогоПриложения") Тогда
ВызватьИсключение "Нужен настоящий объект активного окна приложения";
КонецЕсли;
Если Не ГлавноеОкно.Основное Или СтрНайти(ГлавноеОкно.Заголовок, МеткаСеанса) = 0 Тогда
ВызватьИсключение "Активным должно быть основное окно только своего помеченного клиента";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура СобратьСвоиКнопки(ОбъектИнтерфейса, Заголовок, Найденные, Глубина)
Если Глубина > 12 Тогда
ВызватьИсключение "Учебная иерархия команд оказалась слишком глубокой";
КонецЕсли;
Дочерние = ОбъектИнтерфейса.ПолучитьПодчиненныеОбъекты();
Если ТипЗнч(Дочерние) <> Тип("ФиксированныйМассив") Или Дочерние.Количество() > 200 Тогда
ВызватьИсключение "Нужна настоящая небольшая иерархия своего интерфейса";
КонецЕсли;
Для Каждого Дочерний Из Дочерние Цикл
Если ТипЗнч(Дочерний) = Тип("ТестируемаяКнопкаКомандногоИнтерфейса") Тогда
Если Дочерний.ТекстЗаголовка = Заголовок Тогда
Найденные.Добавить(Дочерний);
КонецЕсли;
ИначеЕсли ТипЗнч(Дочерний) = Тип("ТестируемаяГруппаКомандногоИнтерфейса") Тогда
Сообщить("Группа настоящего интерфейса: " + Дочерний.ТекстЗаголовка);
СобратьСвоиКнопки(Дочерний, Заголовок, Найденные, Глубина + 1);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Функция ПолучитьЕдинственнуюСвоюКнопку(Интерфейс, Заголовок)
Найденные = Новый Массив;
СобратьСвоиКнопки(Интерфейс, Заголовок, Найденные, 0);
Если Найденные.Количество() <> 1 Тогда
ВызватьИсключение "Нужна ровно одна своя кнопка с точным заголовком: " + Заголовок;
КонецЕсли;
Возврат Найденные[0];
КонецФункции
&НаКлиенте
Функция ПолучитьСвоюСвязаннуюПанель(Интерфейс, Заголовок)
КнопкаПанели = ПолучитьЕдинственнуюСвоюКнопку(Интерфейс, Заголовок);
Окно = КнопкаПанели.ПолучитьСвязанноеОкно();
Если ТипЗнч(Окно) <> Тип("ТестируемоеОкноКлиентскогоПриложения") Тогда
ВызватьИсключение "Нужна кнопка именно своей открытой панели, связанная с настоящим окном";
КонецЕсли;
Если Окно.Заголовок <> Заголовок Или Окно.Основное Или Окно.НачальнаяСтраница Тогда
ВызватьИсключение "Нельзя принять основное окно, начальную страницу или другую панель за свою форму";
КонецЕсли;
Сообщить("Настоящая ссылка своей панели: " + Окно.НавигационнаяСсылка);
Возврат Окно;
КонецФункции
&НаКлиенте
Функция ПолучитьЕдинственнуюСвоюФорму(ГлавноеОкно)
Формы = ГлавноеОкно.НайтиОбъекты(Тип("ТестируемаяФорма"), "Учебное окноА85", , 10);
Если ТипЗнч(Формы) <> Тип("ФиксированныйМассив") Или Формы.Количество() <> 1 Тогда
ВызватьИсключение "В своём окне должна существовать ровно одна подготовленная формаА85";
КонецЕсли;
Форма = ГлавноеОкно.НайтиОбъект(Тип("ТестируемаяФорма"), "Учебное окноА85", , 10);
Если ТипЗнч(Форма) <> Тип("ТестируемаяФорма") Тогда
ВызватьИсключение "Нет настоящей найденной собственной формы";
КонецЕсли;
ПолеМетки = Форма.ПолучитьОбъект(Тип("ТестируемоеПолеФормы"), , "МеткаСеанса", 10);
Если ПолеМетки.ПолучитьОтображаемыйТекст() <> МеткаСеанса Тогда
ВызватьИсключение "Форма не подтвердила фактическую метку своего сеанса";
КонецЕсли;
Возврат Форма;
КонецФункции
&НаКлиенте
Функция ЗавершитьСвойТест(Приложение, Форма, ИсходныйЛимит)
Ошибки = "";
Если Форма <> Неопределено Тогда
Попытка
КнопкаЗавершения = Форма.ПолучитьОбъект(Тип("ТестируемаяКнопкаФормы"), , "ЗавершитьСвойСеанс", 10);
КнопкаЗавершения.Нажать();
Исключение
Ошибки = "Не восстановлены собственные заголовки; завершите свой сеанс вручную: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Если ТипЗнч(ИсходныйЛимит) = Тип("Число") Тогда
Попытка
Приложение.УстановитьМаксимальноеВремяВыполненияДействия(ИсходныйЛимит);
Исключение
Ошибки = Ошибки + " Не восстановлен фактический лимит действий: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Попытка
Приложение.РазорватьСоединение();
Исключение
Ошибки = Ошибки + " Не подтверждён разрыв своего соединения: " + ОписаниеОшибки();
КонецПопытки;
Возврат Ошибки;
КонецФункции
&НаКлиенте
Процедура ВыполнитьСвойТест(Команда)
ПроверитьСвойКонтекст();
Приложение = Новый ТестируемоеПриложение("127.0.0.1", Порт);
СвояФорма = Неопределено;
ИсходныйЛимит = Неопределено;
ОшибкаТеста = "";
Итог = "Реальный результат ещё не получен";
Попытка
Приложение.УстановитьСоединение();
ИсходныйЛимит = Приложение.ПолучитьМаксимальноеВремяВыполненияДействия();
Приложение.УстановитьМаксимальноеВремяВыполненияДействия(10);
ГлавноеОкно = Приложение.ПолучитьАктивноеОкно();
ПроверитьСвойКорень(ГлавноеОкно);
СвояФорма = ПолучитьЕдинственнуюСвоюФорму(ГлавноеОкно);
ГлавноеОкно.Активизировать();
Дочерние = ГлавноеОкно.ПолучитьПодчиненныеОбъекты();
Если ТипЗнч(Дочерние) <> Тип("ФиксированныйМассив") Или Дочерние.Количество() = 0 Тогда
ВызватьИсключение "Нет настоящей иерархии подготовленного собственного окна";
КонецЕсли;
ПервыйОбъект = ГлавноеОкно.ПолучитьОбъект();
Если ПервыйОбъект = Неопределено Тогда
ВызватьИсключение "ПолучитьОбъект без аргументов не вернул действительный подчинённый объект";
КонецЕсли;
Сообщить("Тип первого реального объекта без предположения о его порядке: " + Строка(ТипЗнч(ПервыйОбъект)));
Интерфейс = ГлавноеОкно.ПолучитьКомандныйИнтерфейс();
Если ТипЗнч(Интерфейс) <> Тип("ТестируемыйКомандныйИнтерфейсОкна") Тогда
ВызватьИсключение "Нужен фактический командный интерфейс своего окна";
КонецЕсли;
Сообщить("Заголовок командного интерфейса: " + Интерфейс.ТекстЗаголовка);
Интерфейс.Активизировать();
ОткрытьБ = ПолучитьЕдинственнуюСвоюКнопку(Интерфейс, "Открыть учебное окноБ85");
СсылкаКоманды = ОткрытьБ.НавигационнаяСсылка;
Если ТипЗнч(СсылкаКоманды) <> Тип("Строка") Или СсылкаКоманды = "" Тогда
ВызватьИсключение "Нет настоящей навигационной ссылки именно своей команды открытия";
КонецЕсли;
ОткрытьБ.Активизировать();
ГлавноеОкно.ВыполнитьКоманду(СсылкаКоманды);
ОкноБ = ПолучитьСвоюСвязаннуюПанель(Интерфейс, "Учебное окноБ85");
ОкноБ.Активизировать();
ГлавноеОкно.ПерейтиКПредыдущемуОкну();
ГлавноеОкно.ПерейтиКСледующемуОкну();
ГлавноеОкно.ПерейтиКНачальнойСтранице();
ТекущееОкно = Приложение.ПолучитьАктивноеОкно();
Сообщить("Фактический флаг начальной страницы активного окна: " + Строка(ТекущееОкно.НачальнаяСтраница));
КнопкаА = ПолучитьЕдинственнуюСвоюКнопку(Интерфейс, "Учебное окноА85");
КнопкаА.Нажать();
ОкноА = ПолучитьСвоюСвязаннуюПанель(Интерфейс, "Учебное окноА85");
ОкноА.Активизировать();
ПоказатьТекст = СвояФорма.ПолучитьОбъект(Тип("ТестируемаяКнопкаФормы"), , "ПоказатьСвоеСообщение", 10);
ПоказатьТекст.Нажать();
ОжидаемыйТекст = "Учебное сообщение85: " + МеткаСеанса;
Тексты = ГлавноеОкно.ПолучитьТекстыСообщенийПользователю();
Если ТипЗнч(Тексты) <> Тип("ФиксированныйМассив") Или Тексты.Найти(ОжидаемыйТекст) = Неопределено Тогда
ВызватьИсключение "В открытой панели нет действительного сообщения своего сеанса";
КонецЕсли;
ГлавноеОкно.ВыбратьСообщениеПользователю(ОжидаемыйТекст);
ГлавноеОкно.ЗакрытьПанельСообщенийПользователю();
ПроверитьСвойКорень(ГлавноеОкно);
ОкноБ = ПолучитьСвоюСвязаннуюПанель(Интерфейс, "Учебное окноБ85");
ОкноБ.Закрыть();
ФормыБ = ГлавноеОкно.НайтиОбъекты(Тип("ТестируемаяФорма"), "Учебное окноБ85", , 2);
Если ТипЗнч(ФормыБ) <> Тип("ФиксированныйМассив") Или ФормыБ.Количество() <> 0 Тогда
ВызватьИсключение "Закрытие только собственной формыБ ещё не подтверждено";
КонецЕсли;
ПолучитьЕдинственнуюСвоюФорму(ГлавноеОкно);
Итог = "Настоящее сообщение найдено, закрыта только своя панельБ, своя формаА сохранена";
Исключение
ОшибкаТеста = ОписаниеОшибки();
КонецПопытки;
ОшибкиЗавершения = ЗавершитьСвойТест(Приложение, СвояФорма, ИсходныйЛимит);
Если ОшибкаТеста <> "" Или ОшибкиЗавершения <> "" Тогда
Итог = "Тест не завершён успешно: " + ОшибкаТеста + " " + ОшибкиЗавершения;
ВызватьИсключение Итог;
КонецЕсли;
Итог = Итог + "; фактический лимит восстановлен, собственные заголовки восстановлены, соединение разорвано. Сам тестируемый клиент не закрывался";
КонецПроцедуры
УчебноеОкноА85
УчебныеОкна85 → Общие формы → УчебноеОкноА85 → Модуль
Полный модуль своей управляемой формыА: имя конфигурации возвращает серверная функция без контекста, три командных действия и события ПриОткрытии/ПередЗакрытием выполняются на тонком клиенте; legacy-заголовки изменяются и восстанавливаются только в собственном тестируемом клиенте.
Перем СвойСеансПодготовлен;
Перем ИсходныйЗаголовок;
Перем ИсходныйКраткийЗаголовок;
&НаКлиенте
Процедура ПриОткрытии(Отказ)
ЭтотОбъект.АвтоЗаголовок = Ложь;
ЭтотОбъект.Заголовок = "Учебное окноА85";
СвойСеансПодготовлен = Ложь;
МеткаСеанса = "";
КонецПроцедуры
&НаКлиенте
Процедура ПодготовитьСвойСеанс(Команда)
Если СвойСеансПодготовлен Тогда
ВызватьИсключение "Сначала восстановите свои исходные заголовки";
КонецЕсли;
ИсходныйЗаголовок = ПолучитьЗаголовокКлиентскогоПриложения();
ИсходныйКраткийЗаголовок = ПолучитьКраткийЗаголовокПриложения();
МеткаСеанса = "УчебныеОкна85-" + Строка(Новый УникальныйИдентификатор);
СвойСеансПодготовлен = Истина;
УстановитьЗаголовокКлиентскогоПриложения(МеткаСеанса);
УстановитьКраткийЗаголовокПриложения("Учебный тест85");
Если ПолучитьЗаголовокКлиентскогоПриложения() <> МеткаСеанса
Или ПолучитьКраткийЗаголовокПриложения() <> "Учебный тест85" Тогда
ВызватьИсключение "Legacy-заголовки своего клиента ещё не подтвердились";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПоказатьСвоеСообщение(Команда)
Если Не СвойСеансПодготовлен Или МеткаСеанса = "" Тогда
ВызватьИсключение "Сначала подготовьте свой сеанс";
КонецЕсли;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Учебное сообщение85: " + МеткаСеанса;
Сообщение.Сообщить();
КонецПроцедуры
&НаКлиенте
Процедура ЗавершитьСвойСеанс(Команда)
Если Не СвойСеансПодготовлен Тогда
Возврат;
КонецЕсли;
УстановитьКраткийЗаголовокПриложения(ИсходныйКраткийЗаголовок);
УстановитьЗаголовокКлиентскогоПриложения(ИсходныйЗаголовок);
Если ПолучитьКраткийЗаголовокПриложения() <> ИсходныйКраткийЗаголовок
Или ПолучитьЗаголовокКлиентскогоПриложения() <> ИсходныйЗаголовок Тогда
ВызватьИсключение "Исходные собственные заголовки ещё не восстановлены";
КонецЕсли;
СвойСеансПодготовлен = Ложь;
МеткаСеанса = "";
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
СтандартнаяОбработка = Истина;
Если СвойСеансПодготовлен Тогда
Отказ = Истина;
ТекстПредупреждения = "Сначала восстановите собственные заголовки кнопкой ЗавершитьСвойСеанс";
КонецЕсли;
КонецПроцедуры
УчебноеОкноБ85
УчебныеОкна85 → Общие формы → УчебноеОкноБ85 → Модуль
Полный модуль своей управляемой формыБ: серверная функция без контекста возвращает имя конфигурации, событие ПриОткрытии выполняется на тонком клиенте, без записей базы.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
ЭтотОбъект.АвтоЗаголовок = Ложь;
ЭтотОбъект.Заголовок = "Учебное окноБ85";
КонецПроцедуры
ОткрытьУчебноеОкноА85
УчебныеОкна85 → Общие команды → ОткрытьУчебноеОкноА85 → Модуль
Полный модуль собственной общей команды без параметра в подготовленном учебном разделе: серверная функция читает имя конфигурации, клиент проверяет полученную строку и открывает свою общую форму.
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
ОткрытьФорму("ОбщаяФорма.УчебноеОкноА85");
КонецПроцедуры
ОткрытьУчебноеОкноБ85
УчебныеОкна85 → Общие команды → ОткрытьУчебноеОкноБ85 → Модуль
Полный модуль собственной общей команды без параметра в подготовленном учебном разделе: серверная функция читает имя конфигурации, клиент проверяет полученную строку и открывает свою общую форму.
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
ОткрытьФорму("ОбщаяФорма.УчебноеОкноБ85");
КонецПроцедуры
Разбор по шагам
Менеджер создаёт настоящее ТестируемоеПриложение для явно выделенного локального порта и устанавливает соединение. Реальный активный объект должен быть основным окном и содержать фактическую метку подготовленного клиента.
ФормаА ищется строго по собственному заголовку, при НайтиОбъекты требуется ровно один результат, НайтиОбъект получает действительный объект. Поле формы подтверждает ту же метку; отсутствующее или другое окно — отказ, не выдуманный объект.
ПолучитьПодчиненныеОбъекты окна возвращает действительный фиксированный массив. Для ПолучитьОбъект установленная справка8.5.1.1343 показывает синтаксис без аргументов; здесь именно такой вызов и только диагностика типа фактического первого результата, без догадки о порядке.
Командный интерфейс берётся от настоящего окна, активизируется и обходится только через реальные фиксированные массивы дочерних объектов. Вложенные группы распознаются по действительному типу; рекурсия имеет предел12уровней и200дочерних объектов на один узел.
Уникальная своя кнопка Открыть учебное окноБ85 предоставляет настоящую НавигационнаяСсылка. ВыполнитьКоманду получает именно её, не строку придуманных e1cib-адресов. Кнопка и окно — разные объекты с разными ссылками.
Кнопка открытой панелиБ возвращает настоящее связанное окно. Проверки заголовка, Основное и НачальнаяСтраница запрещают принять главный клиент или домашнюю страницу за панель, которую можно закрыть.
Предыдущее, следующее и начальная страница вызываются у проверенного основного окна. Порядок вкладок не угадывается; фактический флаг текущего окна выводится отдельно. Затем своя панельА выбирается её реальной кнопкой.
Кнопка формыА создаёт настоящее сообщение с меткой сеанса. ПолучитьТекстыСообщенийПользователю читает открытый список, точный текст должен существовать. ВыбратьСообщениеПользователю выбирает именно его без подстановочных символов.
ЗакрытьПанельСообщенийПользователю закрывает панель, а не удаляет все сообщения и не завершает приложение. Затем закрывается только повторно проверенная собственная связанная панельБ; формаА должна остаться.
Завершение пытается восстановить действительные исходные заголовки через свою подтверждённую форму, реальный лимит действий и разорвать соединение независимо друг от друга. Ошибки очистки не скрываются, успех выводится только после всех проверок.
Как проверить результат
Чужая конфигурация, другая версия, отсутствие /TESTMANAGER, занятый не своим клиентом порт, несовпавшая фактическая метка или неосновное активное окно должны приводить к отказу, а не выбору первого подходящего объекта.
У формыА должна быть ровно одна фактическая копия с точным заголовком и той же меткой. Шаблоны * и ? не принимаются. Поиск нескольких объектов и проверка количества не заменяются доступом к индексу пустого массива.
Кнопка открытияБ и кнопка уже открытой панелиБ — разные реальные объекты. Первая даёт ссылку команды, вторая — связанное окно. Нет ручного конструктора ТестируемоеОкноКлиентскогоПриложения или присваивания readonly-свойств.
Сообщение в тестируемом клиенте должно содержать тот же UUID, а не заранее сгенерированный ответ. При закрытой панели сообщений getter может выбросить исключение: это честный отказ, не пустой успешный результат.
Закрытие основного окна или начальной страницы запрещено. После закрытияБ поиск собственной формыБ даёт пустой фиксированный массив, а своя формаА и клиент остаются открытыми.
Проверьте восстановление исходного длинного и краткого заголовков в тестируемом клиенте. Они сохранены до изменения и не заменяются на угаданные значения по умолчанию.
При ошибке теста выполняются независимые попытки восстановления заголовков, лимита и разрыва соединения. Ошибка хотя бы одной части не превращается в успешный Итог.
Ожидаемый результат
В разрешённом ручном UI-тесте фактическая команда открывает только своё окноБ, находится настоящее сообщение UUID-сеанса, панельБ закрывается адресно, формаА остаётся, свои исходные заголовки и лимит восстановлены и соединение разорвано. Здесь выполнены только статические проверки.
На что обратить внимание
Это штатная автоматизация 1С, не тест HTML в браузере. /TESTMANAGER и /TESTCLIENT нужны двум собственным клиентам, а порт должен быть подтверждён администратором до соединения.
Заголовок и UUID — диагностические ограждения, не криптографическая аутентификация. Локальный порт может принадлежать чужому клиенту, поэтому новый пустой стенд и ручная проверка принадлежности обязательны.
Свойства окна, группы, интерфейса и кнопки readonly. Создать их вручную конструктором нельзя: экземпляры приходят из реального подключённого клиента и его командного интерфейса.
ПолучитьОбъект окна в этой установленной справке имеет синтаксис без параметров, в отличие от одноимённых методов приложения/формы с четырьмя параметрами. Не переносите сигнатуры только по совпадению названия.
ПолучитьСвязанноеОкно применимо к кнопке панели открытых. Кнопка общего действия открытия не обязана иметь связанное окно до исполнения команды.
Переходы между окнами и на начальную страницу требуют Основное=Истина. Неосновному связанному окну нельзя передавать эти действия вместо главного.
ПолучитьТекстыСообщенийПользователю требует видимую панель сообщений. ЗакрытьПанельСообщенийПользователю не равно удалению сообщения; выбор по тексту может применить подстановки, поэтому используется уникальный точный текст без * и ?.
НавигационнаяСсылка кнопки — ссылка команды, у окна — ссылка формы. Не объявляйте их равными и не составляйте URL вручную из непроверенных имён.
Старые функции длинного и краткого заголовков сохранены в8.5.1.1343 ради совместимости, но не рекомендуются с8.3.10. Краткий legacy-заголовок недоступен в режиме Обычное приложение, поэтому стенд только управляемый.
Поиск уникальной кнопки ограничен собственным проверенным интерфейсом. Отсутствующая/скрытая команда или другая конфигурация интерфейса вызывает отказ; сортировка, локализация и оформление могут требовать ручной настройки стенда.
Принудительное завершение процесса может потерять сохранённые исходные заголовки. ПередЗакрытием формыА не является долговечным журналом; нормальная кнопка завершения обязательна.
Код не запускался, runtimeVerifiedScenarios=0. 1С, сеть тестирования, окна и соединения не использовались; рабочие базы, файлы, резервные копии и архивы не менялись.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.