Source-форма управляет настоящим ОтображениеСостояния своего поля. Менеджер читает его через специальное расширение и ограниченно ожидает реальные показ/скрытие, не создавая фиктивный объект прогресса.
Где и как запускать
Полный отдельный модуль формы менеджера тестирования собственного тонкого клиента и два полных supporting-модуля для создания/открытия своей таблицы. В1С не запускался.
Подготовка
НОВАЯ пустая отдельная конфигурация УчебноеСостояниеТаблицы85 на8.5.1.1343, совместимость Не использовать, Русский, интерфейс Такси. Нет рабочих справочников, документов, регистров, общих реквизитов, расширений, подписок и заданий. Только свои формы/команда этого урока; модули вручную пустые до вставки приведённого кода.
Конфигуратор → Общие формы → УчебнаяТаблицаТест85: реквизит МеткаСеанса Строка100, одиночное поле ввода МеткаСеанса с тем же путём и ТолькоПросмотр=Да; реквизит УчебныйДокумент типа ТабличныйДокумент, поле УчебнаяТаблица85 вида ПолеТабличногоДокумента с ПутьКДанным=УчебныйДокумент. Вставьте весь модуль fixture ниже; событие ПриСозданииНаСервере назначьте одноимённой процедуре.
Общая команда ОткрытьУчебнуюТаблицу85: модуль ниже полностью открывает ОбщаяФорма.УчебнаяТаблицаТест85. Включите команду в интерфейс своей подсистемы УчебныеТесты85. Не создавайте похожую команду для рабочего отчёта. Будущая ручная подготовка: сохранить конфигурацию, обновить базу F7.
Будущий ручной запуск ТОЛЬКО собственного стенда: первый отдельный тонкий клиент /TESTCLIENT -TPort15384, второй /TESTMANAGER. Собственный localhost-порт15384 заранее свободен и выделен только этому уроку; если выбран другой собственный порт, одинаково измените ручной ключ и конструктор. Здесь клиенты, порт и сетевое соединение не запускались.
В своём /TESTCLIENT откройте ровно одну собственную форму общей командой. Скопируйте реально показанный МеткаСеанса UUID. В таблице обычным щелчком выберите только R2C1, ячейку Книга; не выделяйте диапазон или объединённый заголовок.
Своя внешняя обработка УчебныйМенеджерТаблицы85 → новая управляемая Форма в /TESTMANAGER: реквизиты Согласие Булево, МеткаСеанса Строка100, Итог Строка1000. Видимые поля с этими путями, Итог ТолькоПросмотр=Да. Команда/кнопка ВыполнитьСвойТест, действие ВыполнитьСвойТест; ПриОткрытии назначьте одноимённой процедуре. Вставьте весь основной модуль, вставьте настоящую скопированную метку и подтвердите Согласие только своему тесту.
В своей общей форме создайте две команды и кнопки ВНЕ табличного поля: ПоказатьСвоёПояснение85 и СкрытьСвоёПояснение85; действия имеют те же имена. Полный fixture содержит оба обработчика. Внешняя кнопка скрытия остаётся доступной при видимом пояснении.
Пояснение локальное: Своя таблица85: пояснение без загрузки и сети. Оно не означает настоящий сетевой запрос, вычисление СКД или завершение фонового задания. Начальный режим — скрыто.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Согласие = Ложь;
МеткаСеанса = "";
Итог = "Сначала подготовьте свою таблицу и выберите только R2C1";
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСвойСтенд()
Если Не Согласие Тогда
ВызватьИсключение "Разрешите только тест своей таблицы без редактирования, файлов и печати";
КонецЕсли;
UUIDМетки = Новый УникальныйИдентификатор(МеткаСеанса);
Если Строка(UUIDМетки) <> МеткаСеанса Тогда
ВызватьИсключение "Скопируйте фактическую метку своего открытого клиента тестирования";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Функция НайтиСвоюТаблицу(Приложение)
Заголовок = "Учебная таблица85 " + МеткаСеанса;
Формы = Приложение.НайтиОбъекты(Тип("ТестируемаяФорма"), Заголовок, , 10);
Если ТипЗнч(Формы) <> Тип("ФиксированныйМассив") Или Формы.Количество() <> 1 Тогда
ВызватьИсключение "Должна быть одна фактически открытая собственная форма";
КонецЕсли;
Форма = Приложение.ПолучитьОбъект(Тип("ТестируемаяФорма"), Заголовок, , 10);
Метка = Форма.ПолучитьОбъект(Тип("ТестируемоеПолеФормы"), , "МеткаСеанса", 10);
Если Метка.ПолучитьПредставлениеДанных() <> МеткаСеанса Тогда
ВызватьИсключение "Не подтверждена настоящая метка собственной таблицы";
КонецЕсли;
Поле = Форма.ПолучитьОбъект(Тип("ТестируемоеПолеФормы"), , "УчебнаяТаблица85", 10);
Если ТипЗнч(Поле) <> Тип("ТестируемоеПолеФормы") Или Поле.Имя <> "УчебнаяТаблица85"
Или Поле.Вид <> ВидПоляФормы.ПолеТабличногоДокумента Тогда
ВызватьИсключение "Нужно своё поле именно вида ПолеТабличногоДокумента";
КонецЕсли;
Если Не Поле.ТекущаяВидимость() Или Не Поле.ТекущаяДоступность() Тогда
ВызватьИсключение "Собственное поле должно быть видимым и доступным для выбора ячейки";
КонецЕсли;
Возврат Поле;
КонецФункции
&НаКлиенте
Процедура ПроверитьСвоюМатрицу(Поле)
Если Поле.ПолучитьРазмерОбластиДанныхДокументаПоВертикали() <> 3
Или Поле.ПолучитьРазмерОбластиДанныхДокументаПоГоризонтали() <> 2 Тогда
ВызватьИсключение "Свой документ должен иметь последние данные в строке3 и колонке2";
КонецЕсли;
Если Поле.ПолучитьТекстОбласти("R1C1") <> "Учебная таблица85"
Или Поле.ПолучитьТекстОбласти("R2C1") <> "Книга"
Или Поле.ПолучитьТекстОбласти("R2C2") <> "3"
Или Поле.ПолучитьТекстОбласти("R3C1") <> "Ручка"
Или Поле.ПолучитьТекстОбласти("R3C2") <> "1" Тогда
ВызватьИсключение "Все пять текстов собственной таблицы должны совпасть полностью";
КонецЕсли;
Объединение = Поле.ВходитВОбъединеннуюОбласть("R1C1");
Если ТипЗнч(Объединение) <> Тип("Строка") Или Объединение <> "R1C1:R1C2" Тогда
ВызватьИсключение "Заголовок должен входить именно в собственную объединённую область";
КонецЕсли;
Если Поле.ВходитВОбъединеннуюОбласть("R2C1") <> Неопределено Тогда
ВызватьИсключение "Ячейка Книга не должна быть объединена";
КонецЕсли;
Если Поле.ТекущийРежимРедактирование() Тогда
ВызватьИсключение "Не начинайте редактировать собственную таблицу этого урока";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ВыполнитьСвойТест(Команда)
ПроверитьСвойСтенд();
Приложение = Новый ТестируемоеПриложение("127.0.0.1", 15384);
Поле = Неопределено;
ИсходныйЛимит = Неопределено;
СвояОбластьПодтверждена = Ложь;
Скрыть = Неопределено;
ПараметрыПроверки = Неопределено;
Условие = Неопределено;
Ошибка = "";
Итог = "Проверка ещё не завершена";
Попытка
Приложение.УстановитьСоединение();
ИсходныйЛимит = Приложение.ПолучитьМаксимальноеВремяВыполненияДействия();
Приложение.УстановитьМаксимальноеВремяВыполненияДействия(10);
Поле = НайтиСвоюТаблицу(Приложение);
ПроверитьСвоюМатрицу(Поле);
Если Поле.ПолучитьАдресТекущейОбласти() <> "R2C1" Тогда
ВызватьИсключение "До старта вручную выберите одну собственную ячейку Книга, R2C1";
КонецЕсли;
СвояОбластьПодтверждена = Истина;
СвояФорма = Приложение.ПолучитьОбъект(Тип("ТестируемаяФорма"), "Учебная таблица85 " + МеткаСеанса, , 10);
Показать = СвояФорма.ПолучитьОбъект(Тип("ТестируемаяКнопкаФормы"), , "ПоказатьСвоёПояснение85", 10);
Скрыть = СвояФорма.ПолучитьОбъект(Тип("ТестируемаяКнопкаФормы"), , "СкрытьСвоёПояснение85", 10);
ПараметрыПроверки = Новый Структура("Поле,Показать", Поле, Ложь);
Условие = Новый ОписаниеОповещения("СвоёПояснениеДостиглоСостояния85", ЭтотОбъект, ПараметрыПроверки);
Если Не Приложение.ОжидатьСостояния(Условие, 5) Тогда
ВызватьИсключение "До теста собственное пояснение должно быть скрыто";
КонецЕсли;
Показать.Нажать();
ПараметрыПроверки.Показать = Истина;
Если Не Приложение.ОжидатьСостояния(Условие, 5) Тогда
ВызватьИсключение "Собственное пояснение не подтвердилось за ограниченное ожидание";
КонецЕсли;
Скрыть.Нажать();
ПараметрыПроверки.Показать = Ложь;
Если Не Приложение.ОжидатьСостояния(Условие, 5) Тогда
ВызватьИсключение "Своё пояснение не вернулось в скрытое состояние";
КонецЕсли;
ПроверитьСвоюМатрицу(Поле);
Исключение
Ошибка = ОписаниеОшибки();
КонецПопытки;
Если СвояОбластьПодтверждена Тогда
Попытка
Если Скрыть <> Неопределено Тогда
Скрыть.Нажать();
ПараметрыПроверки.Показать = Ложь;
Если Не Приложение.ОжидатьСостояния(Условие, 5) Тогда
ВызватьИсключение "Своё пояснение не скрыто при завершении";
КонецЕсли;
КонецЕсли;
Поле.УстановитьТекущуюОбласть("R2C1");
Если Поле.ПолучитьАдресТекущейОбласти() <> "R2C1" Тогда
ВызватьИсключение "Не восстановлена подтверждённая исходная ячейка";
КонецЕсли;
ПроверитьСвоюМатрицу(Поле);
Исключение
Ошибка = Ошибка + " Восстановление собственной области: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Если ТипЗнч(ИсходныйЛимит) = Тип("Число") Тогда
Попытка
Приложение.УстановитьМаксимальноеВремяВыполненияДействия(ИсходныйЛимит);
Исключение
Ошибка = Ошибка + " Восстановление фактического лимита: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Попытка
Приложение.РазорватьСоединение();
Исключение
Ошибка = Ошибка + " Разрыв собственного соединения: " + ОписаниеОшибки();
КонецПопытки;
Если Ошибка <> "" Тогда
Итог = "Свой тест не завершён: " + Ошибка;
ВызватьИсключение Итог;
КонецЕсли;
Итог = "Своё локальное пояснение показано и скрыто с ограниченной проверкой; матрица и исходная область сохранены, лимит и соединение восстановлены";
КонецПроцедуры
&НаКлиенте
Функция СвоёПояснениеДостиглоСостояния85(ДополнительныеПараметры) Экспорт
Поле = ДополнительныеПараметры.Поле;
Состояние = Поле.ПолучитьОтображениеСостояния();
Если Состояние = Неопределено Тогда
Возврат Не ДополнительныеПараметры.Показать;
КонецЕсли;
Если ТипЗнч(Состояние) <> Тип("ОтображениеСостояния") Тогда
ВызватьИсключение "Native результат должен быть ОтображениеСостояния или Неопределено";
КонецЕсли;
Если Состояние.Текст <> "Своя таблица85: пояснение без загрузки и сети" Тогда
ВызватьИсключение "Получено не собственное локальное пояснение";
КонецЕсли;
Возврат Состояние.Видимость = ДополнительныеПараметры.Показать;
КонецФункцииУчебнаяТаблицаТест85
Конфигуратор → Общие формы → УчебнаяТаблицаТест85 → Модуль
Полный самостоятельный модуль управляемой общей формы: создание собственной таблицы на сервере; не выполнялся.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПроверитьСвойПустойСтенд();
МеткаСеанса = Строка(Новый УникальныйИдентификатор);
ЭтотОбъект.АвтоЗаголовок = Ложь;
ЭтотОбъект.Заголовок = "Учебная таблица85 " + МеткаСеанса;
Документ = Новый ТабличныйДокумент;
Заголовок = Документ.Область(1, 1, 1, 2);
Заголовок.Объединить();
Заголовок.Текст = "Учебная таблица85";
Документ.Область(2, 1).Текст = "Книга";
Документ.Область(2, 2).Текст = "3";
Документ.Область(3, 1).Текст = "Ручка";
Документ.Область(3, 2).Текст = "1";
Документ.Область(1, 1, 3, 2).ШиринаКолонки = 30;
Документ.ТолькоПросмотр = Истина;
УчебныйДокумент = Документ;
СостояниеПоля = Элементы.УчебнаяТаблица85.ОтображениеСостояния;
СостояниеПоля.Текст = "Своя таблица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 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПоказатьСвоёПояснение85(Команда)
СостояниеПоля = Элементы.УчебнаяТаблица85.ОтображениеСостояния;
СостояниеПоля.Видимость = Истина;
КонецПроцедуры
&НаКлиенте
Процедура СкрытьСвоёПояснение85(Команда)
СостояниеПоля = Элементы.УчебнаяТаблица85.ОтображениеСостояния;
СостояниеПоля.Видимость = Ложь;
КонецПроцедурыОткрытьУчебнуюТаблицу85
Конфигуратор → Общие команды → ОткрытьУчебнуюТаблицу85 → Модуль
Полный модуль собственной общей команды с ОбработкаКоманды; не выполнялся.
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
ОткрытьФорму("ОбщаяФорма.УчебнаяТаблицаТест85");
КонецПроцедурыРазбор по шагам
ОтображениеСостояния поля — readonly-ссылка на реальный объект. Fixture не вызывает Новый ОтображениеСостояния и не присваивает новую ссылку: он задаёт текст и меняет Видимость полученного объекта.
Менеджер получает ОтображениеСостояния через Поле.ПолучитьОтображениеСостояния. Неопределено — допустимый native-результат и считается достигнутым только для ожидаемого скрытого состояния, никогда для ожидаемого видимого.
Если объект есть, проверяются его реальный тип, полный собственный текст и Видимость. Экспортная функция возвращает Булево, принимает дополнительные параметры ОписаниеОповещения и используется в ОжидатьСостояния с таймаутом5секунд.
После собственной кнопки показ должен подтвердиться, после скрытия — вернуться в исходное состояние. Нет цикла Пока со сном, поддельного процента или молчаливого принятия истёкшего таймаута.
В завершении отдельно скрывается своё пояснение, проверяется неизменённая матрица, восстанавливаются R2C1, фактический лимит и соединение.
Как проверить результат
Будущий результат: ожидание исходного скрытия, реального показа и последующего скрытия возвращает Истина; все тексты таблицы остаются прежними.
Будущий отрицательный контроль: в своём fixture измените текст пояснения, откройте новую собственную форму и скопируйте новый UUID. Проверка должна отклонить чужой для эталона текст, а не принять любую видимую панель.
Длительность ожидания зависит также от выполняемых внутри callback методов. Здесь каждой проверке дан конечный таймаут и реально существующее своё поле.
Ожидаемый результат
Своё локальное пояснение показано и скрыто с ограниченной проверкой; матрица и исходная область сохранены, лимит и соединение восстановлены
На что обратить внимание
runtimeVerifiedScenarios=0: BSL, UI, клиенты тестирования, соединения, файлы и печать здесь не запускались. Это полные исходники для будущего ручного опыта только на своём стенде.
Нужен новый отдельный /TESTCLIENT только этого урока, не рабочая конфигурация и не общий тестовый клиент. Настоящий UUID копируется из своей формы; ни похожие имена, ни новый выдуманный UUID не заменяют подтверждение источника.
У разных уроков одинаковые имена модулей/форм/процедур, но разные точные имена конфигураций. Каждый урок готовится отдельно; модули не склеивать.
Неопределено не доказывает завершение произвольной загрузки или успешность бизнес-операции. В этом уроке оно означает только отсутствие отображаемого объекта в контроле собственного пояснения.
Показ/скрытие не являются тестом времени формирования рабочего отчёта. Поле содержит только заранее построенные собственные данные.
Get-объект менеджера не используется для присваивания свойств UI. Изменение Видимость делает собственный source-обработчик; менеджер только проверяет результат.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.