Осуществляет поиск среди иерархии подчиненных объектов по указанным параметрам.
Синтаксис
НайтиОбъекты(<Тип>, <ТекстЗаголовка>, <Имя>, <Таймаут>)Полное описание, параметры и ограничения
ТестируемоеПриложение.НайтиОбъекты (TestedApplication.FindObjects)
ТестируемоеПриложение (TestedApplication)
НайтиОбъекты (FindObjects)
Доступен, начиная с версии 8.3.1.
Синтаксис:
НайтиОбъекты(<Тип>, <ТекстЗаголовка>, <Имя>, <Таймаут>)
Параметры:
<Тип> (необязательный)
Тип: Тип.
Тип объекта, которое нужно найти.
Значение по умолчанию: Неопределено.
<ТекстЗаголовка> (необязательный)
Тип: Строка.
Заголовок объекта, если это применимо. Может содержать знаки подстановки "*" и "?".
<Имя> (необязательный)
Тип: Строка.
Имя объекта, если это применимо. Может содержать знаки подстановки "*" и "?".
<Таймаут> (необязательный)
Тип: Число.
Время в секундах, в течение которого выполняется поиск объекта. Если значение параметра не задано, время поиска не ограничено.
Значение по умолчанию: 0.
Возвращаемое значение:
Тип: ФиксированныйМассив.
Фиксированный массив найденных объектов.
Описание:
Осуществляет поиск среди иерархии подчиненных объектов по указанным параметрам.
Доступность:
Тонкий клиент, толстый клиент.
Использование в версии:
Доступен, начиная с версии 8.3.1.
Описание изменено в версии 8.3.27.
Методическая информация
Практические примеры
Проверить собственные формы, активное окно и наличие ошибки
Читаем дерево и состояние клиента тестирования, не закрывая приложение и не нажимая системные окна.
Где и как запускать
Полный клиентский модуль формы обработки в менеджере тестов, запущенном с /TESTMANAGER. Это не модуль тестируемой таблицы.
Подготовка
Создайте собственную пустую учебную конфигурацию УчебнаяКонфигурацияСинтаксиса. Первый урок содержит полный модуль отдельной внешней обработки УчебнаяТаблицаТестирования; её данные только в памяти.
Запустите два отдельных тонких клиента собственной учебной базы: тестируемый с /TESTCLIENT -TPort15380, менеджер с /TESTMANAGER. Порт 15380 — собственный учебный; убедитесь, что на нём не работает другой клиент. Не подключайте менеджер к рабочей базе/чужому приложению.
В тестируемом клиенте вручную откройте собственную обработку из первого урока. В менеджере создайте другую внешнюю обработку с командой ВыполнитьПример; полный код одного теста вставьте в её модуль формы.
Перед каждым тестом закройте и заново откройте таблицу в тестируемом клиенте. Исходно в ней A-01/Книга/3, B-02/Ручка/1, C-00/Бумага/2, без ранее установленной сортировки и редактирования.
Каждый тест ищет точный учебный заголовок и таблицу ТаблицаТоваров внутри этой формы. Не заменяйте селекторы на * или первый найденный элемент рабочего приложения.
Это код штатного механизма тестирования 1С, не браузерная проверка HTML. В данном окружении выполнение UI-тестов в настоящей 1С не подтверждено.
&НаКлиенте
Процедура ВыполнитьПример(Команда)
Приложение = Новый ТестируемоеПриложение("127.0.0.1", 15380);
Приложение.УстановитьСоединение();
ИсходныйЛимит = Неопределено;
ОшибкаТеста = "";
Попытка
Форма = Приложение.ПолучитьОбъект(Тип("ТестируемаяФорма"), "Учебная таблица guide-owned-ui-2026", , 10);
Таблица = Форма.ПолучитьОбъект(Тип("ТестируемаяТаблицаФормы"), , "ТаблицаТоваров", 10);
ИсходныйЛимит = Приложение.ПолучитьМаксимальноеВремяВыполненияДействия();
Приложение.УстановитьМаксимальноеВремяВыполненияДействия(10);
Найденная = Приложение.НайтиОбъект(Тип("ТестируемаяФорма"), "Учебная таблица guide-owned-ui-2026", , 2);
Сообщить(Найденная <> Неопределено);
ВсеУчебные = Приложение.НайтиОбъекты(Тип("ТестируемаяФорма"), "Учебная таблица guide-owned-ui-2026", , 2);
Сообщить("Форм с точным собственным заголовком: " + Строка(ВсеУчебные.Количество()));
Сообщить("Корневых объектов клиента: " + Строка(Приложение.ПолучитьПодчиненныеОбъекты().Количество()));
Окно = Приложение.ПолучитьАктивноеОкно();
Сообщить("Активное окно получено: " + Строка(Окно <> Неопределено));
Ошибка = Приложение.ПолучитьТекущуюИнформациюОбОшибке();
Если Ошибка = Неопределено Тогда
Сообщить("Отображаемого окна ошибки нет");
Иначе
Сообщить("Ошибка содержит собственный маркер: " + Строка(СтрНайти(Ошибка.Описание, "guide-owned-ui-2026") > 0));
Сообщить("Текст/стек ошибки не публикуем и окно автоматически не закрываем");
КонецЕсли;
Исключение
ОшибкаТеста = ОписаниеОшибки();
КонецПопытки;
ОшибкиЗавершения = ЗавершитьСобственныйУчебныйТест(Приложение, ИсходныйЛимит);
Если Не ПустаяСтрока(ОшибкаТеста) Или Не ПустаяСтрока(ОшибкиЗавершения) Тогда
ВызватьИсключение "Ошибка учебного UI-теста: " + ОшибкаТеста + " " + ОшибкиЗавершения;
КонецЕсли;
Сообщить("Сценарий завершён без исключения. Отдельно сверяйте контрольные Истина и видимые данные учебного клиента");
КонецПроцедуры
&НаКлиенте
Функция ЗавершитьСобственныйУчебныйТест(Приложение, ИсходныйЛимит)
ОшибкиЗавершения = "";
Если ТипЗнч(ИсходныйЛимит) = Тип("Число") Тогда
Попытка
Приложение.УстановитьМаксимальноеВремяВыполненияДействия(ИсходныйЛимит);
Исключение
ОшибкиЗавершения = "Не восстановлен лимит действий: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Попытка
Приложение.РазорватьСоединение();
Исключение
ОшибкиЗавершения = ОшибкиЗавершения + " Не разорвано соединение: " + ОписаниеОшибки();
КонецПопытки;
Возврат ОшибкиЗавершения;
КонецФункцииРазбор по шагам
Сначала открываем собственную таблицу в отдельном клиенте тестирования. Подключаемся только к 127.0.0.1:15380, ищем точный заголовок и внутреннее имя таблицы с таймаутами 10 секунд.
НайтиОбъект при отсутствии возвращает Неопределено, НайтиОбъекты — фиксированный массив. Даже при точном заголовке может быть несколько открытых копий; не берём элемент 0 без проверки.
ПолучитьПодчиненныеОбъекты показывает корневые тестируемые объекты, не все строки данных базы. ПолучитьАктивноеОкно не гарантирует, что это именно наша обработка.
ПолучитьТекущуюИнформациюОбОшибке возвращает ИнформацияОбОшибке только если в тестируемом клиенте отображается окно ошибки. Неопределено — нормальное отсутствие.
Для отдельной ручной проверки в расширенном fixture нажмите УчебнаяОшибка. Затем запустите чтение в менеджере: проверяется только собственный маркер, не выводится полный стек.
Никакого Нажать на активное системное окно, закрытия или перезапуска приложения здесь нет. Если ошибка блокирует действия, закройте распознанное собственное окно вручную.
После теста восстанавливаем исходный лимит действий и отдельно пытаемся разорвать соединение, даже при исключении. Ошибки завершения не скрываем; разрыв соединения не закрывает тестируемое приложение.
Как проверить результат
Собственная форма найдена; число точных совпадений соответствует реально открытым копиям.
Без отображаемой ошибки выводится её отсутствие. Для контролируемой ошибки с кнопки проверка маркера должна дать Истина; чужой текст не публикуется.
Ожидаемый результат
Разобрана разница между поиском объекта, активным окном и текущей ошибкой клиента.
На что обратить внимание
Не интерпретируйте отсутствие окна ошибки как отсутствие всех ошибок приложения.
Активное окно не является безопасным селектором для произвольного подтверждения или закрытия.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Проверить настоящую строку поиска: свой UUID, доступность, иерархия и три результата отсутствующего поиска
Полная пара модулей создаёт собственный буквальный список и его настоящее автоматическое дополнение. Тест-менеджер находит его по реальному имени Source-формы, ограниченно проверяет доступность, исследует настоящую иерархию и различает пустой массив, Неопределено и исключение.
Где и как запускать
Полный клиентский модуль своей внешней обработки МенеджерПоиска85.Пульт в /TESTMANAGER; собственный тонкий /TESTCLIENT этой же пустой базы УчебноеТестированиеПоиска85 на вручную проверенном127.0.0.1:15383. Код в1С не выполнялся.
Подготовка
НОВАЯ отдельная пустая файловая база точно8.5.1.1343. Конфигурация УчебноеТестированиеПоиска85, язык Русский, совместимость Не использовать; никаких бизнес-объектов, расширений, подписок, заданий или рабочих данных. Модули конфигурации вручную пустые. Не применять к БП/КА2/УТ/УНФ.
Создайте внешнюю обработку SourceПоиска85 с одной пустой управляемой основной формой. Реквизиты: Список — ДинамическийСписок; МеткаСеанса, ПаспортСтенда, ИмяДополнения — Строка100; ПрофильПоиска — Строка30. Один ТаблицаФормы с именем ТаблицаТоваров и ПутьКДанным=Список. Колонки вручную НЕ добавлять: fixture создает ровно пять своих колонок.
Покажите МеткаСеанса, ПаспортСтенда, ИмяДополнения, ПрофильПоиска отдельными полями ввода с одноименными ПутьКДанным и ТолькоПросмотр=Да. Полный дополнительный модуль ниже вставить в модуль Source-формы. Назначить ПриСозданииНаСервере одноименной процедуре. Он создает две свои кнопки, их вручную не дублировать.
В Source-форме буквальный список: Книга3×250, Ручка1×30, Чай2×150, Вода0×70. ОсновнаяТаблица пустая, ключи УчебныйНомер1–4; автоматическое сохранение пользовательских настроек выключено. UUID и ИмяДополнения берутся именно от настоящей открытой Source-формы, не выдумываются менеджером.
Создайте отдельную внешнюю обработку МенеджерПоиска85 с управляемой формой Пульт. Реквизиты Согласие — Булево; МеткаСеанса — Строка100; Итог — Строка неограниченной длины. Покажите редактируемый флажок, поле точной метки и многострочный Итог только для просмотра. Команда ВыполнитьСвойТест85 с таким действием и одна кнопка. Основной модуль урока вставить в Пульт; назначить ПриОткрытии.
Будущая ручная подготовка: сохранить обе свои внешние обработки, сохранить пустую конфигурацию и обновить ТОЛЬКО свою базу F7. Самостоятельно запустить два своих тонких клиента этой же базы: /TESTCLIENT -TPort15383 и /TESTMANAGER. Сначала убедиться, что 127.0.0.1:15383 принадлежит только своему тестовому клиенту. Код не запускает клиентов, не выбирает другую базу и не меняет порт.
В /TESTCLIENT вручную открыть SourceПоиска85. Убедиться в четырех буквальных строках и профиле Разрешен. Скопировать точное фактическое МеткаСеанса в свой МенеджерПоиска85 в /TESTMANAGER. Подтвердить Согласие. Во время опыта не редактировать и не закрывать Source-форму; менять только доступность ее собственными кнопками.
runtimeVerifiedScenarios=0: никакие 1С, GUI, TCP-соединения, формы и клики здесь не выполнялись. Сверены исходники и установленная справка; настоящий переход состояний, состав иерархии, тексты подсказок, отсутствие объектов и ошибки еще нуждаются в разрешенном ручном тесте.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Согласие = Ложь;
МеткаСеанса = "";
Итог = "Вручную откройте свою source-форму в /TESTCLIENT и перенесите ее настоящий UUID";
КонецПроцедуры
&НаКлиенте
Функция СвойТекст85(Форма, Имя)
Поле = Форма.ПолучитьОбъект(Тип("ТестируемоеПолеФормы"), , Имя, 10);
Если Поле.Имя <> Имя Тогда
ВызватьИсключение "Не совпало собственное контрольное поле";
КонецЕсли;
Возврат Поле.ПолучитьПредставлениеДанных();
КонецФункции
&НаКлиенте
Функция СвоеДополнение85(Форма, Имя)
Найденные = Форма.НайтиОбъекты(Тип("ТестируемоеДополнениеЭлементаФормы"), , Имя, 10);
Если ТипЗнч(Найденные) <> Тип("ФиксированныйМассив") Или Найденные.Количество() <> 1 Тогда
ВызватьИсключение "Нужно ровно одно реальное собственное дополнение с именем из source-формы";
КонецЕсли;
Поиск = Найденные[0];
Если ТипЗнч(Поиск) <> Тип("ТестируемоеДополнениеЭлементаФормы") Или Поиск.Имя <> Имя
Или Поиск.Вид <> ВидДополненияЭлементаФормы.ОтображениеСтрокиПоиска Тогда
ВызватьИсключение "Получен не собственный объект строки поиска";
КонецЕсли;
Возврат Поиск;
КонецФункции
&НаКлиенте
Функция СобственныйПоискДостигПрофиля85(ПараметрыПроверки) Экспорт
Если СвойТекст85(ПараметрыПроверки.Форма, "МеткаСеанса") <> ПараметрыПроверки.Метка
Или СвойТекст85(ПараметрыПроверки.Форма, "ПаспортСтенда") <> "own-tested-search85-four-literals-no-business-data" Тогда
ВызватьИсключение "Источник ожидания перестал быть собственным сеансом";
КонецЕсли;
Поиск = СвоеДополнение85(ПараметрыПроверки.Форма, ПараметрыПроверки.Имя);
Возврат СвойТекст85(ПараметрыПроверки.Форма, "ПрофильПоиска") = ПараметрыПроверки.Профиль
И Поиск.ТекущаяДоступность() = ПараметрыПроверки.Разрешен;
КонецФункции
&НаКлиенте
Функция ОписатьСвойТестовыйОбъект85(Объект)
Если Объект = Неопределено Тогда
Возврат "Неопределено: объект не предоставлен";
КонецЕсли;
ВидОбъекта = ТипЗнч(Объект);
Если ВидОбъекта = Тип("ТестируемаяГруппаФормы") Или ВидОбъекта = Тип("ТестируемоеПолеФормы") Тогда
Возврат Строка(ВидОбъекта) + ": " + Объект.Имя + "; " + Объект.ТекстЗаголовка;
КонецЕсли;
Возврат "Реальный тип: " + Строка(ВидОбъекта);
КонецФункции
&НаКлиенте
Функция ОписатьСвоюИерархию85(Поиск, Метка)
Дочерние = Поиск.ПолучитьПодчиненныеОбъекты();
Если ТипЗнч(Дочерние) <> Тип("ФиксированныйМассив") Или Дочерние.Количество() > 64 Тогда
ВызватьИсключение "Неожиданная коллекция дочерних объектов собственного дополнения";
КонецЕсли;
Отчет = "Дочерних UI-объектов: " + Строка(Дочерние.Количество()) + Символы.ПС;
Для Каждого Дочерний Из Дочерние Цикл
Отчет = Отчет + ОписатьСвойТестовыйОбъект85(Дочерний) + Символы.ПС;
КонецЦикла;
Родитель = Поиск.ПолучитьРодителя();
Отчет = Отчет + "Родитель: " + ОписатьСвойТестовыйОбъект85(Родитель) + Символы.ПС;
ОтсутствующееИмя = "Уч85Отсутствует_" + Метка;
НетОбъектов = Поиск.НайтиОбъекты(, , ОтсутствующееИмя, 1);
Если ТипЗнч(НетОбъектов) <> Тип("ФиксированныйМассив") Или НетОбъектов.Количество() <> 0 Тогда
ВызватьИсключение "Отрицательный контроль встретил реальный объект: опыт прекращен";
КонецЕсли;
Если Поиск.НайтиОбъект(, , ОтсутствующееИмя, 1) <> Неопределено Тогда
ВызватьИсключение "НайтиОбъект должен вернуть Неопределено для подтвержденного отсутствующего имени";
КонецЕсли;
ОшибкаОтсутствия = "";
НеожиданныйРезультат = Неопределено;
Попытка
НеожиданныйРезультат = Поиск.ПолучитьОбъект(, , ОтсутствующееИмя, 1);
Исключение
ОшибкаОтсутствия = ОписаниеОшибки();
КонецПопытки;
Если ОшибкаОтсутствия = "" Тогда
ВызватьИсключение "ПолучитьОбъект не сообщил об отсутствии: " + Строка(ТипЗнч(НеожиданныйРезультат));
КонецЕсли;
Отчет = Отчет + "Отрицательный поиск: пустой массив, Неопределено, исключение ПолучитьОбъект" + Символы.ПС;
Отчет = Отчет + "Реальный текст исключения: " + ОшибкаОтсутствия + Символы.ПС;
Попытка
Панель = Поиск.ПолучитьКоманднуюПанель();
Отчет = Отчет + "Командная панель: " + ОписатьСвойТестовыйОбъект85(Панель) + Символы.ПС;
Исключение
Отчет = Отчет + "Панель НЕ получена для этого вида дополнения: " + ОписаниеОшибки() + Символы.ПС;
КонецПопытки;
Попытка
Меню = Поиск.ПолучитьКонтекстноеМеню();
Отчет = Отчет + "Контекстное меню: " + ОписатьСвойТестовыйОбъект85(Меню) + Символы.ПС;
Исключение
Отчет = Отчет + "Меню НЕ получено для этого вида дополнения: " + ОписаниеОшибки() + Символы.ПС;
КонецПопытки;
Возврат Отчет;
КонецФункции
&НаКлиенте
Процедура ВыполнитьСвойТест85(Команда)
Если Не Согласие Тогда
ВызватьИсключение "Нужны собственный пустой стенд и явное согласие на проверку своей формы";
КонецЕсли;
UUID = Новый УникальныйИдентификатор(МеткаСеанса);
Если Строка(UUID) <> МеткаСеанса Тогда
ВызватьИсключение "Передайте точный UUID настоящей source-формы, не придуманную метку";
КонецЕсли;
Приложение = Новый ТестируемоеПриложение("127.0.0.1", 15383);
ИсходныйЛимит = Неопределено;
Разрешить = Неопределено;
ДанныеОжидания = Неопределено;
ОшибкаТеста = "";
ОшибкиЗавершения = "";
Итог = "Тест еще не завершен";
Попытка
Приложение.УстановитьСоединение();
ИсходныйЛимит = Приложение.ПолучитьМаксимальноеВремяВыполненияДействия();
Приложение.УстановитьМаксимальноеВремяВыполненияДействия(10);
Заголовок = "Уч85ТестПоиска " + МеткаСеанса;
Формы = Приложение.НайтиОбъекты(Тип("ТестируемаяФорма"), Заголовок, , 10);
Если ТипЗнч(Формы) <> Тип("ФиксированныйМассив") Или Формы.Количество() <> 1 Тогда
ВызватьИсключение "Нужна единственная собственная форма этого UUID";
КонецЕсли;
Форма = Приложение.ПолучитьОбъект(Тип("ТестируемаяФорма"), Заголовок, , 10);
Если СвойТекст85(Форма, "МеткаСеанса") <> МеткаСеанса
Или СвойТекст85(Форма, "ПаспортСтенда") <> "own-tested-search85-four-literals-no-business-data"
Или СвойТекст85(Форма, "ПрофильПоиска") <> "Разрешен" Тогда
ВызватьИсключение "Источник или исходный собственный профиль не совпал; чужие состояния не сбрасываются";
КонецЕсли;
Имя = СвойТекст85(Форма, "ИмяДополнения");
Если Имя = "" Или СтрНайти(Имя, "*") > 0 Или СтрНайти(Имя, "?") > 0 Тогда
ВызватьИсключение "Нужно точное реальное имя дополнения без поисковых шаблонов";
КонецЕсли;
Поиск = СвоеДополнение85(Форма, Имя);
Если Не Поиск.ТекущаяВидимость() Или Не Поиск.ТекущаяДоступность() Тогда
ВызватьИсключение "Собственная строка поиска должна быть видна и доступна до начала опыта";
КонецЕсли;
ДанныеОжидания = Новый Структура("Форма,Метка,Имя,Профиль,Разрешен", Форма, МеткаСеанса, Имя, "Разрешен", Истина);
Разрешить = Форма.ПолучитьОбъект(Тип("ТестируемаяКнопкаФормы"), , "КнопкаРазрешитьПоиск85", 10);
Запретить = Форма.ПолучитьОбъект(Тип("ТестируемаяКнопкаФормы"), , "КнопкаЗапретитьПоиск85", 10);
Поиск.Активизировать();
ЗаголовокПоиска = Поиск.ТекстЗаголовка;
Подсказка = Поиск.ПолучитьТекстПодсказки();
ТолькоПросмотр = Поиск.ТекущееТолькоПросмотр();
Если ТипЗнч(ЗаголовокПоиска) <> Тип("Строка") Или ТипЗнч(Подсказка) <> Тип("Строка")
Или ТипЗнч(ТолькоПросмотр) <> Тип("Булево") Тогда
ВызватьИсключение "Не совпали документированные типы реального UI-дополнения";
КонецЕсли;
Отчет = "Собственное имя: " + Поиск.Имя + Символы.ПС;
Отчет = Отчет + "Реальный заголовок: " + ЗаголовокПоиска + Символы.ПС;
Отчет = Отчет + "Реальная подсказка: " + Подсказка + Символы.ПС;
Отчет = Отчет + "Только просмотр по API: " + Строка(ТолькоПросмотр) + Символы.ПС;
Отчет = Отчет + ОписатьСвоюИерархию85(Поиск, МеткаСеанса);
Запретить.Нажать();
ДанныеОжидания.Профиль = "Запрещен";
ДанныеОжидания.Разрешен = Ложь;
Условие = Новый ОписаниеОповещения("СобственныйПоискДостигПрофиля85", ЭтотОбъект, ДанныеОжидания);
Если Не Приложение.ОжидатьСостояния(Условие, 5) Тогда
ВызватьИсключение "В пределах собственного ожидания недоступность не подтверждена";
КонецЕсли;
Разрешить.Нажать();
ДанныеОжидания.Профиль = "Разрешен";
ДанныеОжидания.Разрешен = Истина;
Если Не Приложение.ОжидатьСостояния(Условие, 5) Тогда
ВызватьИсключение "Обратная доступность собственной строки не подтверждена";
КонецЕсли;
Итог = Отчет + "Обязательные проверки исходного профиля, отрицательного поиска и двух переходов завершены";
Исключение
ОшибкаТеста = ОписаниеОшибки();
КонецПопытки;
Если Разрешить <> Неопределено И ДанныеОжидания <> Неопределено Тогда
Попытка
Разрешить.Нажать();
ДанныеОжидания.Профиль = "Разрешен";
ДанныеОжидания.Разрешен = Истина;
Восстановление = Новый ОписаниеОповещения("СобственныйПоискДостигПрофиля85", ЭтотОбъект, ДанныеОжидания);
Если Не Приложение.ОжидатьСостояния(Восстановление, 5) Тогда
ВызватьИсключение "Исходная доступность собственного дополнения не восстановлена";
КонецЕсли;
Исключение
ОшибкиЗавершения = "Восстановление НЕ подтверждено: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Если ТипЗнч(ИсходныйЛимит) = Тип("Число") Тогда
Попытка
Приложение.УстановитьМаксимальноеВремяВыполненияДействия(ИсходныйЛимит);
Исключение
ОшибкиЗавершения = ОшибкиЗавершения + " Лимит НЕ восстановлен: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Попытка
Приложение.РазорватьСоединение();
Исключение
ОшибкиЗавершения = ОшибкиЗавершения + " Соединение НЕ разорвано: " + ОписаниеОшибки();
КонецПопытки;
Если ОшибкаТеста <> "" Или ОшибкиЗавершения <> "" Тогда
Итог = "Опыт НЕ завершен: " + ОшибкаТеста + " " + ОшибкиЗавершения;
ВызватьИсключение Итог;
КонецЕсли;
Итог = Итог + Символы.ПС + "Исходная доступность и лимит восстановлены; соединение разорвано. Диагностика меню/панели не доказывает их поддержку";
КонецПроцедурыSourceПоиска85
УчебноеТестированиеПоиска85 → Своя внешняя обработка SourceПоиска85 → Управляемая основная форма → Модуль
Полный модуль собственной Source-формы: серверная защита пустого стенда и буквальный список, клиентские кнопки и настоящий автоматический поиск; без бизнес-чтений/записи.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПроверитьСвойПустойСтенд();
Список.ПроизвольныйЗапрос = Истина;
Список.ОсновнаяТаблица = "";
Список.ДинамическоеСчитываниеДанных = Ложь;
Список.АвтоЗаполнениеДоступныхПолей = Истина;
Список.АвтоматическоеСохранениеПользовательскихНастроек = Ложь;
Список.ВидКлюча = ВидКлючаДинамическогоСписка.ЗначениеПоля;
КлючевыеПоля = Новый Массив;
КлючевыеПоля.Добавить("УчебныйНомер");
Список.ПоляКлюча = Новый ФиксированныйМассив(КлючевыеПоля);
Список.ТекстЗапроса = "ВЫБРАТЬ
| 1 КАК УчебныйНомер,
| ""Книга"" КАК Наименование,
| ""Канцелярия"" КАК Категория,
| 3 КАК Количество,
| 250 КАК Цена
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ 2, ""Ручка"", ""Канцелярия"", 1, 30
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ 3, ""Чай"", ""Продукты"", 2, 150
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ 4, ""Вода"", ""Продукты"", 0, 70";
Элементы.ТаблицаТоваров.ТолькоПросмотр = Истина;
МеткаСеанса = Строка(Новый УникальныйИдентификатор);
ПаспортСтенда = "own-tested-search85-four-literals-no-business-data";
ЭтаФорма.АвтоЗаголовок = Ложь;
ЭтаФорма.Заголовок = "Уч85ТестПоиска " + МеткаСеанса;
Элементы.ТаблицаТоваров.ПоложениеСтрокиПоиска = ПоложениеСтрокиПоиска.Верх;
ДобавитьСвоюКнопку85("РазрешитьПоиск85", "Разрешить собственный поиск");
ДобавитьСвоюКнопку85("ЗапретитьПоиск85", "Запретить собственный поиск");
Для Каждого ИмяПоля Из СтрРазделить("УчебныйНомер,Наименование,Категория,Количество,Цена", ",") Цикл
Колонка = Элементы.Добавить("Товары" + ИмяПоля, Тип("ПолеФормы"), Элементы.ТаблицаТоваров);
Колонка.Вид = ВидПоляФормы.ПолеВвода;
Колонка.ПутьКДанным = "Список." + ИмяПоля;
Колонка.Заголовок = ИмяПоля;
КонецЦикла;
УстановитьСвойПоиск85(Истина);
КонецПроцедуры
&НаСервере
Процедура ДобавитьСвоюКнопку85(Имя, Заголовок)
Команда = Команды.Добавить(Имя);
Команда.Действие = Имя;
Команда.Заголовок = Заголовок;
Кнопка = Элементы.Добавить("Кнопка" + Имя, Тип("КнопкаФормы"));
Кнопка.ИмяКоманды = Имя;
КонецПроцедуры
&НаСервере
Процедура УстановитьСвойПоиск85(Разрешен)
ПроверитьСвойПустойСтенд();
Если ТипЗнч(Разрешен) <> Тип("Булево") Или ПаспортСтенда <> "own-tested-search85-four-literals-no-business-data" Тогда
ВызватьИсключение "Нужен собственный буквальный стенд и логический профиль";
КонецЕсли;
Поиск = Элементы.ТаблицаТоваров.ОтображениеСтрокиПоиска;
Если ТипЗнч(Поиск) <> Тип("ДополнениеЭлементаФормы")
Или Поиск.Вид <> ВидДополненияЭлементаФормы.ОтображениеСтрокиПоиска Тогда
ВызватьИсключение "Нужно реальное автоматическое дополнение собственной таблицы";
КонецЕсли;
ИмяДополнения = Поиск.Имя;
Если ИмяДополнения = "" Тогда
ВызватьИсключение "Платформа не предоставила имя собственного дополнения";
КонецЕсли;
Поиск.Заголовок = "Уч85ПоискЧетырехСтрок";
Поиск.Подсказка = "Только Книга, Ручка, Чай, Вода из собственного буквального списка";
Поиск.ОтображениеПодсказки = ОтображениеПодсказки.Всплывающая;
Поиск.Доступность = Разрешен;
Если Поиск.Доступность <> Разрешен Тогда
ВызватьИсключение "Сервер не сохранил собственный профиль доступности";
КонецЕсли;
ПрофильПоиска = ?(Разрешен, "Разрешен", "Запрещен");
КонецПроцедуры
&НаКлиенте
Процедура РазрешитьПоиск85(Команда)
УстановитьСвойПоиск85(Истина);
КонецПроцедуры
&НаКлиенте
Процедура ЗапретитьПоиск85(Команда)
УстановитьСвойПоиск85(Ложь);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедурыРазбор по шагам
Source-модуль сам создаёт уникальный UUID, точный заголовок, собственный паспорт, список четырех констант, пять колонок и две кнопки. Это действительное дополнение ТаблицаТоваров.ОтображениеСтрокиПоиска с видом ОтображениеСтрокиПоиска, не произвольный ИсходныйОбъект и не Новый тестируемый элемент.
До соединения менеджер проверяет явное согласие. После соединения ограничивает действия10секундами и требует ровно одну форму с UUID, совпадающие контрольные поля и исходный разрешенный профиль. Только потом получает дополнение по фактическому имени без * и ?.
Имя и Вид — readonly-паспорт тестового объекта. Активизировать работает только с идентифицированной собственной строкой. ТекстЗаголовка, реальная подсказка и ТолькоПросмотр читаются с проверкой типов; их содержание выводится фактически, а не заменяется заранее обещанным текстом виджета.
ПолучитьПодчиненныеОбъекты возвращает ФиксированныйМассив UI-объектов. Число дочерних элементов не равно числу товаров. Родитель диагностируется по реальному типу: в коде нет обязательного предположения, что он всегда таблица или группа.
Отрицательное имя содержит действительный UUID. Сначала НайтиОбъекты подтверждает пустой фиксированный массив; НайтиОбъект затем должен дать Неопределено. ПолучитьОбъект проверяется отдельной Попыткой: отсутствие должно вызвать исключение. Реальный текст ошибки выводится, но не сравнивается посимвольно и не подменяется выдуманным кодом ошибки.
ПолучитьКоманднуюПанель и ПолучитьКонтекстноеМеню — отдельные диагностические запросы возможностей именно этого вида. Возвращённые объекты/Неопределено/исключения сохраняются в отчёте. Фраза НЕ получено означает неуспешное получение; она не превращается в доказательство поддержки панели или меню.
Две собственные кнопки вызывают серверную смену Доступность и отдельное текстовое состояние Source-формы. Экспортная функция ОписаниеОповещения проверяет и фактическую ТекущаяДоступность, и профиль, и неизменные UUID/паспорт. ОжидатьСостояния с5секундами не заменяется бесконечным циклом или немедленным обещанием результата после нажатия.
Даже после ошибки отдельно предпринимаются восстановление исходной доступности, исходного лимита действий и разрыв соединения. Их ошибки сохраняются, вызывается итоговое исключение. Клиент и обе формы остаются открытыми; данные списка, текст поиска, бизнес-объекты и файлы тест не изменяет.
Как проверить результат
Будущий ручной контроль: source-таблица показывает именно Книга/Ручка/Чай/Вода; тестовый менеджер получает ее действительный UUID и имя дополнения, не другой клиент или форму.
Обязательные проверки: исходная видимость/доступность; пустой массив по отсутствующему UUID-имени; Неопределено у НайтиОбъект; настоящее исключение ПолучитьОбъект; переход Разрешен→Запрещен→Разрешен и независимое восстановление перед разрывом соединения.
Диагностика: фактические заголовок, подсказка, ТолькоПросмотр, количество дочерних UI-объектов, тип родителя и возможности меню/панели. Не требуйте заранее придуманного числа дочерних объектов, фиксированного родителя или обязательного наличия панели.
Отрицательный ручной контроль: другой UUID или выключенное Согласие должны остановить тест. Если перед началом Source-профиль Запрещен, менеджер отклоняет его и не нажимает восстановление. После начала собственных изменений можно временно исказить ожидаемый профиль в менеджере: ограниченное ожидание должно завершиться ошибкой, а отдельная ветка завершения вернуть доступность.
runtimeVerifiedScenarios=0: никакого утверждения, что реальный UI-тест уже прошёл. Неуспешное получение диагностической панели/меню не считается успешной проверкой этих возможностей.
Ожидаемый результат
Есть полный воспроизводимый Source-стенд и тест-менеджер с реальным объектом, контролем принадлежности сеансу, ограниченными проверками, явным отчетом возможностей и независимым завершением.
На что обратить внимание
ТестируемоеДополнениеЭлементаФормы — абстракция существующего виджета; конструктора нет, свойства не записываются. Вид определяется источником. Доступная функциональность зависит от вида дополнения, поэтому отчёт возможностей нельзя выдавать за доказательство успешного получения всех объектов.
НайтиОбъект и ПолучитьОбъект по одному отсутствующему имени ведут себя по-разному. У второго проверяется исключение, а не только Неопределено. Оба поиска ограничены1секундой, остальные10секундами;0 в таймауте поиска означает неограниченное ожидание и здесь не используется.
ТекстЗаголовка/подсказка отражают тестовый интерфейс; он может не показывать весь текст настроек Source-объекта. ТолькоПросмотр не является правом доступа к данным, а Доступность не фильтрует товары.
Метка источника не секрет аутентификации и не защита общего TCP-порта. Порт должен быть заранее проверен вручную; этот урок предназначен только своему локальному стенду, не удалённому/чужому клиенту.
ПолучитьРодителя не обещает определенный тип для любого дополнения. Описатель читает Имя/ТекстЗаголовка только у проверенных тестовых группы/поля; другим объектам не приписывает чужой API.
Ожидаемое исключение отсутствующего поиска — отрицательный контрактный опыт, не общий способ подавления ошибок. Остальные основные ошибки прекращают тест; ошибки меню/панели явно отмечают неподтвержденную возможность.
В учебный код не добавлены ввод текста, очистка пользовательского поиска, сохранение настроек, закрытие формы/клиента или запись базы. Восстановление возвращает только заранее подтвержденный собственный разрешенный профиль.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.