Расширение тестируемого поля формы для поля полосы регулирования

Типы · Tested form field extension for a track bar field

Содержит свойства специфичные для поля вида ПолеПолосыРегулирования.

Полное описание, параметры и ограничения

Расширение тестируемого поля формы для поля полосы регулирования (Tested form field extension for a track bar field)

Расширение тестируемого поля формы для поля полосы регулирования (Tested form field extension for a track bar field)

Доступен, начиная с версии 8.3.6.

Методы:
ПерейтиКЗначению (GotoValue)

Описание:

Содержит свойства специфичные для поля вида ПолеПолосыРегулирования.

Доступность:

Тонкий клиент, толстый клиент.

Использование в версии:

Доступен, начиная с версии 8.3.6.

Методическая информация

Практические примеры

Проверить свой тариф, скидку и предоплату настоящими UI-действиями

Полный собственный калькулятор в памяти и отдельный пульт штатного тестирования: настоящий UUID формы, реальные карты представлений выбора, независимая проверка сумм и два разных события ссылок.

Где и как запускать

Полный модуль собственного пульта МенеджерТарифа85.Пульт, управляемый тонкийWindows /TESTMANAGER 8.5.1.1343; собственный тонкий /TESTCLIENT той же новой пустойИБ на вручную проверенном127.0.0.1:15385. Только авторский исходный код, runtime0.

Подготовка

  1. Ничего не добавляйте в рабочие конфигурации. В собственной отдельной Windows VM вручную создайте новую файловуюИБ только по пути C:\Users\ArsiHard\Documents\ChatGPT\1C 2\ib-quote85-8c0d02c6-6196-4c3b-a01a-36a1a218caa8. Это будущая ручная подготовка, здесь каталог/ИБ/файлы не создавались. Платформа точно8.5.1.1343, собственнаяCF УчебныйРасчетТарифа85, управляемое приложение, Такси, совместимостьНеИспользовать.

  2. Создайте единственного настоящего пользователя guide-quote85 и собственную роль с полными правами только этой одноразовойИБ, включая администрирование для native-полного списка пользователей. Язык конфигурацииРусский, кодru, основной языкРусский; интерфейс и менеджер также русскоязычные. Реальный UUID пользователя возвращает nativeТекущийПользователь и сверяет с единственным элементом nativeМассив; это UUID пользователя, не UUID базы.

  3. Прикладных справочников, документов, перечислений, регистров, планов, разделителей, подписок, заданий, внешних источников и расширений всех трех источников нет. Только общая формаУчебныйТариф85, обработкаМенеджерТарифа85 с формойПульт, общая командаОткрытьТариф85, собственная роль/язык и одна учебная подсистема для команды. Общих модулей нет. Других обработчиков или действий, записывающих данные/файлы/настройки, не добавляйте.

  4. Общие формы → УчебныйТариф85, Управляемая: вставьте полностью supporting module source-quote-form. События формыПриСозданииНаСервере(Отказ,СтандартнаяОбработка) иПриОткрытии(Отказ) назначьте одноименным настоящим процедурам. Форма не имеет основного реквизита объектаБД. Отключите сохранение данных формы в настройках.

  5. Реквизиты source-формы: МеткаСеанса85 иПользователь85 Строка36; Тариф85 Число1,0; Скидка85 Булево; ПредоплатаПроцент85 Число3,0; Сумма85/Аванс85 Число15,2; Шаг85 Число2,0; ПростыхНажатий85/ФорматированныхНажатий85 Число1,0; Остановка85 Булево; Паспорт85 Строка500; Подробности85 Строка1000; ПростаяСсылка85 Строка100; ФорматированнаяСсылка85 ФорматированнаяСтрока. Не включайте типНеопределено/третье состояние дляСкидка85.

  6. Создайте отдельные элементы, не колонки таблицы: Тариф85 видПолеПереключателя/ПутьКДаннымТариф85; Скидка85 видПолеФлажка/ПутьСкидка85; ПредоплатаПроцент85 видПолеПолосыРегулирования/ПутьПредоплатаПроцент85. ИхПриИзменении назначьтеНастройкаПриИзменении85(Элемент). СписокВыбораТариф85 в редакторе оставьте пустым: source-сервер добавит ровно1/Базовый1000 и2/Расширенный1500 в существующую readonly-коллекцию, не присваивая свойство.

  7. Два отдельных элементаПростаяСсылка85 иФорматированнаяСсылка85 имеют видПолеНадписи и одноименныйПутьКДанным. Первому назначьтеНажатие → ПростаяСсылкаНажатие85(Элемент,СтандартнаяОбработка); второмуОбработкаНавигационнойСсылки → ФорматированнаяСсылкаОбработка85(Элемент,НавигационнаяСсылкаФорматированнойСтроки,СтандартнаяОбработка). Гиперссылка первогоИстина, второгоЛожь задает source-код при серверном создании. Никаких декораций вместо настоящих полей не подставляйте.

  8. МеткаСеанса85, Пользователь85, Паспорт85 иПодробности85 выведите отдельными элементамиПолеВвода с одноименными внутренними именами/путями, ВидимостьДа, ТолькоПросмотрДа; Подробности/Паспорт многострочные. Сумма/Аванс/Шаг/счетчики/Остановка также показываются только для чтения. Поля тумблера/переключателя/полосы и обе надписи видимы и доступны. Не ставьте ТолькоПросмотр на всю форму. После настройки source-код сам задает1000/250, скидкуЛожь, тариф1 и25%.

  9. Общая командаОткрытьТариф85: без параметра, включена только в собственную подсистему; вставьте supporting module own-launch-command, событиеОбработкаКоманды назначается предопределенно. Команда открывает толькоОбщаяФорма.УчебныйТариф85.

  10. Обработки → МенеджерТарифа85 → Управляемая формаПульт: основной код целиком сюда. РеквизитыПользователь85 Строка36 (скрытый или только чтение), МеткаСеанса85 Строка36 (ввод), Согласие85 Булево, Начат85/Остановка85 Булево (только чтение), Результат85 Строка неограниченной длины (многострочный/только чтение). СобытиеПриСозданииНаСервере назначьте собственной одноименной процедуре. КомандаВыполнитьСвойТест85 с одноименным действием/кнопкой; ИзменяетСохраняемыеДанныеЛожь. Сохранение данных формы в настройках выключите.

  11. СохранитеCF и вручную обновите только свою новуюИБ. Для будущего теста вручную запустите два собственных тонких клиента этой жеИБ: source с /TESTCLIENT -TPort15385; пульт с /TESTMANAGER. Перед запуском человек проверяет принадлежность свободногоlocalhost-порта15385 только своему source-клиенту. Код не запускает процессы, не проверяет/открывает порты ОС и не выбирает другую базу. При занятости порта не продолжайте.

  12. В /TESTCLIENT откройте одну source-форму собственной командой и скопируйте ее фактическийМеткаСеанса85 в пульт. Не генерируйте вместо нее другойUUID, не редактируйте тумблер/тариф/полосу вручную после подготовки и не открывайте вторую source-форму. После реальногоПриОткрытии паспорт должен показать собственныеUUID/1/0/25/1000.00/250.00/0/0/0.

  13. В пульте подтвердитеСогласие85 и выполните команду ровно один раз. Native-соединение/поиск/виды/доступность/начальный паспорт и реальные карты выбора проверяются до первого изменяющегоUI-действия. Представления данныхДа/Нет или1/2 не угадываются: берутся из native-карты по заданным source-кодом отображаемым текстам.

  14. При успехе отдельный обратный процесс подтверждает исходные тариф1/скидкаЛожь/предоплата25 и1000/250; шаг8, счетчики1/1 и последняя расшифровка намеренно остаются. При любой ошибке source/pult sticky-stop не снимается, автоматического reset/rollback/retry нет. Даже если действие уже применилось, остановитесь и вручную исследуйте только свою форму; не запускайте следующую команду.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Пользователь85 = ПроверитьСредуТарифа85();
    МеткаСеанса85 = "";
    Согласие85 = Ложь;
    Начат85 = Ложь;
    Остановка85 = Ложь;
    Результат85 = "Сначала подготовьте свой /TESTCLIENT и скопируйте настоящий UUID формы";
КонецПроцедуры

&НаКлиенте
Функция ПолучитьСвоюФорму85(Приложение)
    ЗаголовокФормы = "Свой тариф85 " + МеткаСеанса85;
    Формы = Приложение.НайтиОбъекты(Тип("ТестируемаяФорма"), ЗаголовокФормы, , 10);
    Если ТипЗнч(Формы) <> Тип("ФиксированныйМассив") Или Формы.Количество() <> 1 Тогда
        ВызватьИсключение "Нужна ровно одна собственная фактическая форма, не первый похожий объект";
    КонецЕсли;
    Форма = Приложение.ПолучитьОбъект(Тип("ТестируемаяФорма"), ЗаголовокФормы, , 10);
    Если ТипЗнч(Форма) <> Тип("ТестируемаяФорма") Тогда
        ВызватьИсключение "Native фабрика должна вернуть настоящую тестируемую форму";
    КонецЕсли;
    Метка = ПолучитьСвоеПоле85(Форма, "МеткаСеанса85", ВидПоляФормы.ПолеВвода);
    Пользователь = ПолучитьСвоеПоле85(Форма, "Пользователь85", ВидПоляФормы.ПолеВвода);
    Если Метка.ПолучитьПредставлениеДанных() <> МеткаСеанса85
        Или Пользователь.ПолучитьПредставлениеДанных() <> Пользователь85 Тогда
        ВызватьИсключение "Реальная source-форма должна подтвердить свой UUID и настоящего пользователя этой учебнойИБ";
    КонецЕсли;
    Возврат Форма;
КонецФункции

&НаКлиенте
Функция ПолучитьСвоеПоле85(Форма, Имя, Вид)
    Если СтрРазделить("МеткаСеанса85,Пользователь85,Паспорт85,Подробности85,Скидка85,Тариф85,ПредоплатаПроцент85,ПростаяСсылка85,ФорматированнаяСсылка85", ",").Найти(Имя) = Неопределено Тогда
        ВызватьИсключение "Поиск разрешен только среди подготовленных собственных элементов";
    КонецЕсли;
    Найденные = Форма.НайтиОбъекты(Тип("ТестируемоеПолеФормы"), , Имя, 10);
    Если ТипЗнч(Найденные) <> Тип("ФиксированныйМассив") Или Найденные.Количество() <> 1 Тогда
        ВызватьИсключение "Собственное поле должно быть единственным";
    КонецЕсли;
    Поле = Форма.ПолучитьОбъект(Тип("ТестируемоеПолеФормы"), , Имя, 10);
    Если ТипЗнч(Поле) <> Тип("ТестируемоеПолеФормы") Или Поле.Имя <> Имя Или Поле.Вид <> Вид
        Или Не Поле.ТекущаяВидимость() Тогда
        ВызватьИсключение "Нужно реальное собственное поле требуемого native-вида";
    КонецЕсли;
    Возврат Поле;
КонецФункции

&НаКлиенте
Функция ПроверитьКартуВыбора85(Карта, ПервыйТекст, ВторойТекст)
    Если ТипЗнч(Карта) <> Тип("ФиксированныйМассив") Или Карта.Количество() <> 2 Тогда
        ВызватьИсключение "Нужны две реальные записи собственного списка выбора";
    КонецЕсли;
    РезультатКарты = Новый Структура;
    Для Каждого Запись Из Карта Цикл
        Представление = Неопределено;
        Текст = Неопределено;
        Если ТипЗнч(Запись) <> Тип("Структура") Или Запись.Количество() <> 2
            Или Не Запись.Свойство("ПредставлениеДанных", Представление)
            Или Не Запись.Свойство("ОтображаемыйТекст", Текст)
            Или ТипЗнч(Представление) <> Тип("Строка") Или ТипЗнч(Текст) <> Тип("Строка")
            Или Не ЗначениеЗаполнено(Представление) Тогда
            ВызватьИсключение "Точная native-карта русскоязычной конфигурации: две строковые колонки, не придуманные значения";
        КонецЕсли;
        Если Текст = ПервыйТекст И Не РезультатКарты.Свойство("Первый") Тогда
            РезультатКарты.Вставить("Первый", Представление);
        ИначеЕсли Текст = ВторойТекст И Не РезультатКарты.Свойство("Второй") Тогда
            РезультатКарты.Вставить("Второй", Представление);
        Иначе
            ВызватьИсключение "Не совпали собственные явные представления или найден дубль";
        КонецЕсли;
    КонецЦикла;
    Если Не РезультатКарты.Свойство("Первый") Или Не РезультатКарты.Свойство("Второй")
        Или РезультатКарты.Первый = РезультатКарты.Второй Тогда
        ВызватьИсключение "Карта должна различать два фактических представления данных";
    КонецЕсли;
    Возврат РезультатКарты;
КонецФункции

&НаКлиенте
Процедура ПроверитьСостояние85(Форма, Тариф, Скидка, Процент, Шаг, Простые, Форматированные)
    Метка = ПолучитьСвоеПоле85(Форма, "МеткаСеанса85", ВидПоляФормы.ПолеВвода);
    Пользователь = ПолучитьСвоеПоле85(Форма, "Пользователь85", ВидПоляФормы.ПолеВвода);
    Если Метка.ПолучитьПредставлениеДанных() <> МеткаСеанса85 Или Пользователь.ПолучитьПредставлениеДанных() <> Пользователь85 Тогда
        ВызватьИсключение "Identity source-формы изменилась; дальнейшие действия запрещены";
    КонецЕсли;
    База = ?(Тариф = 1, 1000, 1500);
    Сумма = База * ?(Скидка, 0.9, 1);
    Аванс = Сумма * Процент / 100;
    ОжидаемыйПаспорт = МеткаСеанса85 + "|" + Пользователь85 + "|" + Формат(Тариф, "ЧГ=0;ЧДЦ=0;ЧН=0")
        + "|" + ?(Скидка, "1", "0") + "|" + Формат(Процент, "ЧГ=0;ЧДЦ=0;ЧН=0")
        + "|" + Формат(Сумма, "ЧГ=0;ЧДЦ=2;ЧРД=.;ЧН=0.00")
        + "|" + Формат(Аванс, "ЧГ=0;ЧДЦ=2;ЧРД=.;ЧН=0.00")
        + "|" + Формат(Шаг, "ЧГ=0;ЧДЦ=0;ЧН=0")
        + "|" + Формат(Простые, "ЧГ=0;ЧДЦ=0;ЧН=0")
        + "|" + Формат(Форматированные, "ЧГ=0;ЧДЦ=0;ЧН=0");
    Паспорт = ПолучитьСвоеПоле85(Форма, "Паспорт85", ВидПоляФормы.ПолеВвода);
    Если Паспорт.ПолучитьПредставлениеДанных() <> ОжидаемыйПаспорт Тогда
        ВызватьИсключение "Не совпали независимые числовые данные, собственный этап или реальный callback";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьСвойТест85(Команда)
    Если Начат85 Или Остановка85 Тогда
        ВызватьИсключение "Пульт одноразовый: после старта нет повторного выполнения или слепого восстановления";
    КонецЕсли;
    Если Не Согласие85 Или СтрДлина(МеткаСеанса85) <> 36 Или Строка(Новый УникальныйИдентификатор(МеткаСеанса85)) <> МеткаСеанса85 Тогда
        ВызватьИсключение "Подтвердите свой опыт и скопируйте настоящий UUID source-формы";
    КонецЕсли;
    Начат85 = Истина;
    Согласие85 = Ложь;
    Приложение = Новый ТестируемоеПриложение("127.0.0.1", 15385);
    Соединение85 = Ложь;
    Ошибка85 = "";
    Попытка
        Приложение.УстановитьСоединение();
        Соединение85 = Истина;
        Форма = ПолучитьСвоюФорму85(Приложение);
        ПроверитьСостояние85(Форма, 1, Ложь, 25, 0, 0, 0);
        Флажок = ПолучитьСвоеПоле85(Форма, "Скидка85", ВидПоляФормы.ПолеФлажка);
        Переключатель = ПолучитьСвоеПоле85(Форма, "Тариф85", ВидПоляФормы.ПолеПереключателя);
        Ползунок = ПолучитьСвоеПоле85(Форма, "ПредоплатаПроцент85", ВидПоляФормы.ПолеПолосыРегулирования);
        Простая = ПолучитьСвоеПоле85(Форма, "ПростаяСсылка85", ВидПоляФормы.ПолеНадписи);
        Форматированная = ПолучитьСвоеПоле85(Форма, "ФорматированнаяСсылка85", ВидПоляФормы.ПолеНадписи);
        Если Не Флажок.ТекущаяДоступность() Или Не Переключатель.ТекущаяДоступность() Или Не Ползунок.ТекущаяДоступность()
            Или Не Простая.ТекущаяДоступность() Или Не Форматированная.ТекущаяДоступность() Тогда
            ВызватьИсключение "Все свои изменяемые элементы должны быть доступны перед первым действием";
        КонецЕсли;
        КартаФлажка = ПроверитьКартуВыбора85(Флажок.ПолучитьПредставлениеСпискаВыбора(), "Без скидки", "Скидка10%");
        КартаТарифа = ПроверитьКартуВыбора85(Переключатель.ПолучитьПредставлениеСпискаВыбора(), "Базовый1000", "Расширенный1500");
        Если Флажок.ПолучитьОтображаемыйТекст() <> "Без скидки" Или Флажок.ПолучитьПредставлениеДанных() <> КартаФлажка.Первый
            Или Переключатель.ПолучитьОтображаемыйТекст() <> "Базовый1000" Или Переключатель.ПолучитьПредставлениеДанных() <> КартаТарифа.Первый
            Или Простая.ПолучитьОтображаемыйТекст() <> "Показать сумму" Или Форматированная.ПолучитьОтображаемыйТекст() <> "Расшифровать" Тогда
            ВызватьИсключение "Не совпали заданные собственной формой отображения и реальные карты выбора";
        КонецЕсли;
        Ссылки = Форматированная.ПолучитьПредставленияГиперссылокФорматированнойСтроки();
        Если ТипЗнч(Ссылки) <> Тип("ФиксированныйМассив") Или Ссылки.Количество() <> 1 Или Ссылки[0] <> "Расшифровать" Тогда
            ВызватьИсключение "В собственной форматированной строке должна быть ровно одна расчетная ссылка";
        КонецЕсли;
        Флажок.УстановитьОтметку();
        ПроверитьСостояние85(Форма, 1, Истина, 25, 1, 0, 0);
        Если Флажок.ПолучитьОтображаемыйТекст() <> "Скидка10%" Или Флажок.ПолучитьПредставлениеДанных() <> КартаФлажка.Второй Тогда
            ВызватьИсключение "Циклический вызов должен подтвержденно перейти в свой булевИстина, без угадывания третьего состояния";
        КонецЕсли;
        Переключатель.ВыбратьВариант("Расширенный1500");
        ПроверитьСостояние85(Форма, 2, Истина, 25, 2, 0, 0);
        Если Переключатель.ПолучитьОтображаемыйТекст() <> "Расширенный1500"
            Или Переключатель.ПолучитьПредставлениеДанных() <> КартаТарифа.Второй Тогда
            ВызватьИсключение "Не подтвержден свой второй тариф из настоящей карты";
        КонецЕсли;
        Ползунок.ПерейтиКЗначению(50);
        ПроверитьСостояние85(Форма, 2, Истина, 50, 3, 0, 0);
        Простая.Нажать();
        ПроверитьСостояние85(Форма, 2, Истина, 50, 4, 1, 0);
        Детали = ПолучитьСвоеПоле85(Форма, "Подробности85", ВидПоляФормы.ПолеВвода);
        Если Детали.ПолучитьПредставлениеДанных() <> "Сумма1350.00;Аванс675.00" Тогда
            ВызватьИсключение "Реальное нажатие должно вызвать свой обработчик простой надписи";
        КонецЕсли;
        Форматированная.НажатьНаГиперссылкуВФорматированнойСтроке("Расшифровать");
        ПроверитьСостояние85(Форма, 2, Истина, 50, 5, 1, 1);
        Если Детали.ПолучитьПредставлениеДанных() <> "1500.00-150.00=1350.00;1350.00*50/100=675.00" Тогда
            ВызватьИсключение "Свой реальный обработчик должен подтвердить независимый числовой разбор";
        КонецЕсли;
        ПроверитьСостояние85(Форма, 2, Истина, 50, 5, 1, 1);
        Ползунок.ПерейтиКЗначению(25);
        ПроверитьСостояние85(Форма, 2, Истина, 25, 6, 1, 1);
        Переключатель.ВыбратьВариант("Базовый1000");
        ПроверитьСостояние85(Форма, 1, Истина, 25, 7, 1, 1);
        Если Флажок.ПолучитьОтображаемыйТекст() <> "Скидка10%" Или Флажок.ПолучитьПредставлениеДанных() <> КартаФлажка.Второй Тогда
            ВызватьИсключение "Перед обратным циклом необходима подтвержденная свояИстина";
        КонецЕсли;
        Флажок.УстановитьОтметку();
        ПроверитьСостояние85(Форма, 1, Ложь, 25, 8, 1, 1);
        Если Флажок.ПолучитьОтображаемыйТекст() <> "Без скидки" Или Флажок.ПолучитьПредставлениеДанных() <> КартаФлажка.Первый
            Или Переключатель.ПолучитьОтображаемыйТекст() <> "Базовый1000" Тогда
            ВызватьИсключение "Собственные исходные настройки не подтверждены после отдельного обратного процесса";
        КонецЕсли;
        Результат85 = "Подтверждены1000/250 → 900/225 → 1350/337.50 → 1350/675; свои ссылки1/1; настройки снова1000/250. Счетчики/шаг/расшифровка намеренно сохранены.";
    Исключение
        Остановка85 = Истина;
        Ошибка85 = ОписаниеОшибки();
        Результат85 = "СТОП: частичные UI-изменения возможны; автоматического восстановления нет. " + Ошибка85;
    КонецПопытки;
    Если Соединение85 Тогда
        Попытка
            Приложение.РазорватьСоединение();
        Исключение
            Остановка85 = Истина;
            Ошибка85 = Ошибка85 + " Разрыв собственного соединения не подтвержден: " + ОписаниеОшибки();
            Результат85 = "СТОП: " + Ошибка85;
        КонецПопытки;
    КонецЕсли;
    Если ЗначениеЗаполнено(Ошибка85) Тогда
        ВызватьИсключение Ошибка85;
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПроверитьСредуТарифа85()
    ПроверитьСвойПустойСтенд();
    Если Метаданные.ОбщиеФормы.Количество() <> 1 Или Метаданные.ОбщиеФормы.Найти("УчебныйТариф85") = Неопределено
        Или Метаданные.Обработки.Количество() <> 1 Или Метаданные.Обработки.Найти("МенеджерТарифа85") = Неопределено
        Или Метаданные.ОбщиеКоманды.Количество() <> 1 Или Метаданные.ОбщиеКоманды.Найти("ОткрытьТариф85") = Неопределено
        Или Метаданные.ОбщиеМодули.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен точный собственный стенд: одна форма, один пульт и одна общая команда без общих модулей";
    КонецЕсли;
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если ТипЗнч(Пользователи) <> Тип("Массив") Или Пользователи.Количество() <> 1
        Или Текущий = Неопределено Тогда
        ВызватьИсключение "Нужен один собственный настоящий пользователь ИБ";
    КонецЕсли;
    Если Пользователи[0].УникальныйИдентификатор <> Текущий.УникальныйИдентификатор
        Или Текущий.Имя <> "guide-quote85" Тогда
        ВызватьИсключение "Текущий пользователь должен быть единственным пользователем собственного стенда";
    КонецЕсли;
    Возврат Строка(Текущий.УникальныйИдентификатор);
КонецФункции

&НаСервереБезКонтекста
Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры
source-quote-form

УчебныйРасчетТарифа85 → Общие формы → УчебныйТариф85 → Модуль, целиком.

Полный модуль собственной управляемой общей формы: серверная подготовка и реальные клиентские native-события; данные только в памяти.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Пользователь85 = ПроверитьСредуТарифа85();
    МеткаСеанса85 = Строка(Новый УникальныйИдентификатор);
    Тариф85 = 1;
    Скидка85 = Ложь;
    ПредоплатаПроцент85 = 25;
    Сумма85 = 1000;
    Аванс85 = 250;
    Шаг85 = 0;
    ПростыхНажатий85 = 0;
    ФорматированныхНажатий85 = 0;
    Остановка85 = Ложь;
    Подробности85 = "Расчет еще не открывался";
    ПростаяСсылка85 = "Показать сумму";
    ФорматированнаяСсылка85 = Новый ФорматированнаяСтрока("Расшифровать", , , , "quote85:" + МеткаСеанса85);
    Элементы.Скидка85.ВидФлажка = ВидФлажка.Тумблер;
    Элементы.Скидка85.ТриСостояния = Ложь;
    Элементы.Скидка85.ФорматРедактирования = "БЛ=Без скидки;БИ=Скидка10%";
    Если Элементы.Тариф85.СписокВыбора.Количество() <> 0 Тогда
        ВызватьИсключение "Список своего переключателя заполняется только один раз при создании";
    КонецЕсли;
    Элементы.Тариф85.СписокВыбора.Добавить(1, "Базовый1000");
    Элементы.Тариф85.СписокВыбора.Добавить(2, "Расширенный1500");
    Элементы.ПредоплатаПроцент85.МинимальноеЗначение = 0;
    Элементы.ПредоплатаПроцент85.МаксимальноеЗначение = 100;
    Элементы.ПредоплатаПроцент85.Шаг = 1;
    Элементы.ПростаяСсылка85.Гиперссылка = Истина;
    Элементы.ФорматированнаяСсылка85.Гиперссылка = Ложь;
    Заголовок = "Свой тариф85 " + МеткаСеанса85;
    Паспорт85 = "";
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    ПересчитатьИПодтвердить85();
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСвоюОткрытуюФорму85()
    Если Остановка85 Тогда
        ВызватьИсключение "СТОП: после ошибки нельзя продолжать или сбрасывать свой опыт вслепую";
    КонецЕсли;
    Если СтрДлина(МеткаСеанса85) <> 36 Или Строка(Новый УникальныйИдентификатор(МеткаСеанса85)) <> МеткаСеанса85 Или СтрДлина(Пользователь85) <> 36 Или Заголовок <> "Свой тариф85 " + МеткаСеанса85 Тогда
        ВызватьИсключение "Не совпала собственная подготовленная форма и ее реальные UUID";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПересчитатьИПодтвердить85()
    ПроверитьСвоюОткрытуюФорму85();
    Если ТипЗнч(Тариф85) <> Тип("Число") Или Тариф85 <> 1 И Тариф85 <> 2
        Или ТипЗнч(Скидка85) <> Тип("Булево") Или ТипЗнч(ПредоплатаПроцент85) <> Тип("Число")
        Или ПредоплатаПроцент85 <> 25 И ПредоплатаПроцент85 <> 50 Тогда
        ВызватьИсключение "Только свои два тарифа, булева скидка и подготовленные25/50процентов";
    КонецЕсли;
    ЦенаТарифа = ?(Тариф85 = 1, 1000, 1500);
    Сумма85 = ЦенаТарифа - ?(Скидка85, ЦенаТарифа / 10, 0);
    Аванс85 = Сумма85 / 100 * ПредоплатаПроцент85;
    Паспорт85 = МеткаСеанса85 + "|" + Пользователь85 + "|" + Формат(Тариф85, "ЧГ=0;ЧДЦ=0;ЧН=0")
        + "|" + ?(Скидка85, "1", "0") + "|" + Формат(ПредоплатаПроцент85, "ЧГ=0;ЧДЦ=0;ЧН=0")
        + "|" + Формат(Сумма85, "ЧГ=0;ЧДЦ=2;ЧРД=.;ЧН=0.00")
        + "|" + Формат(Аванс85, "ЧГ=0;ЧДЦ=2;ЧРД=.;ЧН=0.00")
        + "|" + Формат(Шаг85, "ЧГ=0;ЧДЦ=0;ЧН=0")
        + "|" + Формат(ПростыхНажатий85, "ЧГ=0;ЧДЦ=0;ЧН=0")
        + "|" + Формат(ФорматированныхНажатий85, "ЧГ=0;ЧДЦ=0;ЧН=0");
КонецПроцедуры

&НаКлиенте
Процедура НастройкаПриИзменении85(Элемент)
    Попытка
        ПроверитьСвоюОткрытуюФорму85();
        Если Элемент = Элементы.Скидка85 И Шаг85 = 0 И Скидка85 И Тариф85 = 1 И ПредоплатаПроцент85 = 25 Тогда
            Шаг85 = 1;
        ИначеЕсли Элемент = Элементы.Тариф85 И Шаг85 = 1 И Тариф85 = 2 И Скидка85 И ПредоплатаПроцент85 = 25 Тогда
            Шаг85 = 2;
        ИначеЕсли Элемент = Элементы.ПредоплатаПроцент85 И Шаг85 = 2 И ПредоплатаПроцент85 = 50 И Тариф85 = 2 И Скидка85 Тогда
            Шаг85 = 3;
        ИначеЕсли Элемент = Элементы.ПредоплатаПроцент85 И Шаг85 = 5 И ПредоплатаПроцент85 = 25 И Тариф85 = 2 И Скидка85
            И ПростыхНажатий85 = 1 И ФорматированныхНажатий85 = 1 Тогда
            Шаг85 = 6;
        ИначеЕсли Элемент = Элементы.Тариф85 И Шаг85 = 6 И Тариф85 = 1 И Скидка85 И ПредоплатаПроцент85 = 25 Тогда
            Шаг85 = 7;
        ИначеЕсли Элемент = Элементы.Скидка85 И Шаг85 = 7 И Не Скидка85 И Тариф85 = 1 И ПредоплатаПроцент85 = 25 Тогда
            Шаг85 = 8;
        Иначе
            ВызватьИсключение "Неожиданное UI-изменение или порядок: частичный результат не сбрасываем";
        КонецЕсли;
        ПересчитатьИПодтвердить85();
    Исключение
        Остановка85 = Истина;
        Паспорт85 = "STOP|" + МеткаСеанса85 + "|" + ОписаниеОшибки();
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ПростаяСсылкаНажатие85(Элемент, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Попытка
        ПроверитьСвоюОткрытуюФорму85();
        Если Элемент <> Элементы.ПростаяСсылка85 Или Шаг85 <> 3 Или ПростыхНажатий85 <> 0
            Или ФорматированныхНажатий85 <> 0 Или Тариф85 <> 2 Или Не Скидка85 Или ПредоплатаПроцент85 <> 50
            Или Сумма85 <> 1350 Или Аванс85 <> 675 Тогда
            ВызватьИсключение "Нажатие разрешено только для собственного подтвержденного расчета1350/675";
        КонецЕсли;
        Подробности85 = "Сумма1350.00;Аванс675.00";
        ПростыхНажатий85 = 1;
        Шаг85 = 4;
        ПересчитатьИПодтвердить85();
    Исключение
        Остановка85 = Истина;
        Паспорт85 = "STOP|" + МеткаСеанса85 + "|" + ОписаниеОшибки();
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ФорматированнаяСсылкаОбработка85(Элемент, НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Попытка
        ПроверитьСвоюОткрытуюФорму85();
        Если Элемент <> Элементы.ФорматированнаяСсылка85
            Или НавигационнаяСсылкаФорматированнойСтроки <> "quote85:" + МеткаСеанса85
            Или Шаг85 <> 4 Или ПростыхНажатий85 <> 1 Или ФорматированныхНажатий85 <> 0
            Или Тариф85 <> 2 Или Не Скидка85 Или ПредоплатаПроцент85 <> 50
            Или Сумма85 <> 1350 Или Аванс85 <> 675 Тогда
            ВызватьИсключение "Разрешена только своя единственная расчетная ссылка без внешнего перехода";
        КонецЕсли;
        РасчетнаяЦена = 1500;
        РасчетнаяСкидка = РасчетнаяЦена * 0.1;
        РасчетнаяСумма = РасчетнаяЦена - РасчетнаяСкидка;
        РасчетныйАванс = РасчетнаяСумма * 0.5;
        Если РасчетнаяСумма <> Сумма85 Или РасчетныйАванс <> Аванс85 Тогда
            ВызватьИсключение "Независимый числовой разбор не совпал с собственной формой";
        КонецЕсли;
        Подробности85 = "1500.00-150.00=1350.00;1350.00*50/100=675.00";
        ФорматированныхНажатий85 = 1;
        Шаг85 = 5;
        ПересчитатьИПодтвердить85();
    Исключение
        Остановка85 = Истина;
        Паспорт85 = "STOP|" + МеткаСеанса85 + "|" + ОписаниеОшибки();
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПроверитьСредуТарифа85()
    ПроверитьСвойПустойСтенд();
    Если Метаданные.ОбщиеФормы.Количество() <> 1 Или Метаданные.ОбщиеФормы.Найти("УчебныйТариф85") = Неопределено
        Или Метаданные.Обработки.Количество() <> 1 Или Метаданные.Обработки.Найти("МенеджерТарифа85") = Неопределено
        Или Метаданные.ОбщиеКоманды.Количество() <> 1 Или Метаданные.ОбщиеКоманды.Найти("ОткрытьТариф85") = Неопределено
        Или Метаданные.ОбщиеМодули.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен точный собственный стенд: одна форма, один пульт и одна общая команда без общих модулей";
    КонецЕсли;
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если ТипЗнч(Пользователи) <> Тип("Массив") Или Пользователи.Количество() <> 1
        Или Текущий = Неопределено Тогда
        ВызватьИсключение "Нужен один собственный настоящий пользователь ИБ";
    КонецЕсли;
    Если Пользователи[0].УникальныйИдентификатор <> Текущий.УникальныйИдентификатор
        Или Текущий.Имя <> "guide-quote85" Тогда
        ВызватьИсключение "Текущий пользователь должен быть единственным пользователем собственного стенда";
    КонецЕсли;
    Возврат Строка(Текущий.УникальныйИдентификатор);
КонецФункции

&НаСервереБезКонтекста
Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры
own-launch-command

УчебныйРасчетТарифа85 → Общие команды → ОткрытьТариф85 → Модуль, целиком.

Полный клиентский модуль своей общей команды без параметра.

&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    ОткрытьФорму("ОбщаяФорма.УчебныйТариф85");
КонецПроцедуры

Разбор по шагам

  1. NativeTestedApplication связывается только с заранее подготовленным собственнымlocalhost-клиентом; UUID-заголовок и отдельныеreadonly-поля подтверждают одну фактическую форму и UUID настоящего пользователя. Это диагностические guards, не аутентификация TCP-клиента или доказательство пути/изоляцииИБ.

  2. Сначала проверяются1/Ложь/25 и независимые1000/250. Для каждого элемента источник — nativeНайтиОбъекты сCount1, затемПолучитьОбъект; реальныйТипТестируемоеПолеФормы, Имя иВид исключают декорации, колонки таблицы и одноименные обычные расширения.

  3. Native-карты тумблера и переключателя должны бытьФиксированныйМассив из двухСтруктура сПредставлениеДанных/ОтображаемыйТекст. Отображаемые подписи задает полный source-код; фактическое представление данных берется из карты. Язык конфигурации менеджера определяет имена полей карты.

  4. УстановитьОтметку() не принимаетИстина/Ложь: циклический переход допускается только после подтверждения собственного исходногоЛожь и двух состояний. Настоящий callback даетскидку10% и900/225, а actual-map/readback дополнительно подтверждаютИстина.

  5. ВыбратьВариант("Расширенный1500") выбирает реальное представление собственной записи, не значение2 по ошибке как индекс. Native callback и независимый паспорт дают1350/337.50; отображаемый текст/карта также проверены.

  6. ПерейтиКЗначению(50) означает50процентов. Source-полоса специально имеет диапазон0…100 и шаг1; проверка реального callback/паспорта должна дать1350/675, а не предполагаемый результат любого диапазона.

  7. Нажать() на обычной надписиГиперссылкаИстина вызывает свойНажатие сЭлемент+СтандартнаяОбработка. СначалаStandardFalse, затем проверка своего этапа/сумм; реальные счетчик1/шаг4/подробности подтверждают событие, вручную обработчик не вызывается.

  8. Форматированная надписьГиперссылкаЛожь содержит одну настоящуюФорматированнаяСтрока ссобственнойquote85:UUID. Native-коллекция представлений должна датьРасшифровать; реальное нажатие вызываетОбработкаНавигационнойСсылки сЭлемент+2nativeпараметра. StandardFalse первым исключает стандартный переход, handler принимает только свою точную строку и показывает независимый1500−150=1350/50%=675.

  9. После подтвержденногошага5/счетчиков1/1 выполняются отдельные обратные50→25%, тариф2→1 и подтвержденнаяИстина→Ложь. Каждый промежуточный собственный паспорт проверяется; вcatch восстановление не вызывается. Чужой/неожиданный state не перезаписывается.

  10. Соединение разрывается отдельно после success или failure, еслиnativeConnect уже подтвердил его установку. ОшибкаDisconnect сохраняется какСТОП. Клиент, source-форма и пульт не закрываются; никаких документов/БД/файлов/настроек не записывается.

Как проверить результат

  1. Исходно настоящий UUID формы/пользователя ипаспорт1/0/25/1000.00/250.00/0/0/0. При нескольких формах, чужом пользователе/UUID или неверномВид тест отказывает до действия.

  2. Последовательность numerical-readback:1000/250 → 900/225 → 1350/337.50 → 1350/675. Ни одно GUI-действие не объявляется успешным без фактического source-паспорта после реального callback.

  3. Простое нажатие:шаг4/счетчики1,0/Сумма1350.00;Аванс675.00. Форматированное:шаг5/1,1 иточный независимыйразбор1500.00-150.00=1350.00;1350.00*50/100=675.00.

  4. Успешный обратный процесс даетшаг8/1,1 иисходные1000/250; карта/отображениеФлажка сноваБез скидки, тарифаБазовый1000. Это восстановление настроек собственного fixture, не всей исходной формы: счетчики/подробности остаются.

  5. Ошибочный native-return, иной состав карты/ссылок, callback не вызван, неожиданный этап/данные или частичный результат → sticky-stop. Слепого повторного теста/обратного переключения/закрытия/очистки нет.

Ожидаемый результат

При успешном будущем ручном UI-тесте ожидаются реальные числовые readbacks1000/250→900/225→1350/337.50→1350/675, собственные события ссылок1/1 и подтвержденный возврат настроек1000/250. Здесь подготовлены только исходники/статические тесты; TESTCLIENT/TESTMANAGER/1С/UI/сеть не запускались.

На что обратить внимание

  1. Ключи с@Tested относятся к fingerprint-тестируемым расширениям, доступным через настоящийТестируемоеПолеФормы соответствующегоВид. Newextension, ordinarycontrols и одноименныеForm field extension не являются этими объектами.

  2. NativeSetCheck циклический; нельзя передатьИстина или рассчитывать на третье состояние/OS-представление. Source явноБулево/ТриСостоянияЛожь/Тумблер/ФорматРедактирования. NativeChoiceListPresentations наблюдается, не подделывается; несовпадение карты означаетСТОП, а не исправлениеreadonly-объекта.

  3. СписокВыбора переключателяreadonly: Add меняет элементы собственного коллекционного значения на сервере при создании, присваиванияСписокВыбора нет. Настройки тумблера/полосы также задаются на сервере до открытия, не из клиентского события с неявнымсерверным вызовом.

  4. Форматированная строка — реальное native-значение с5constructor-slots и собственной ссылкой. PlainClick иFormattedClick — разные поля/режимы/события; нельзя привязать оба кдекорации или вызывать event-процедуры вместо nativeUI-действий.

  5. ПриИзменении не вызывается вручную. Статические проверки доказывают nativeсигнатуры исвязи authoredfixture, но не выполненную генерацию событий/отрисовку/коллекции в1С; будущий тест проверяет счетчики/числа и остановится, если фактический callback/readback не произошел.

  6. UI-действия не атомарны. Защиты не устраняют конкурентное вмешательство/подмену TCP-сервера; до теста человек изолирует свою VM/ИБ/порты и не взаимодействует соsource-формой. После частичной ошибки ничего автоматически не восстанавливается.

  7. Цифры паспорта иподробностей форматируются сявнымдесятичнымразделителемточка/безгруппировки; не зависят от OSlocale. Представления данных вкартах остаются native-наблюдениями и не приравниваются ккультурно-зависимымДа/Нет/1/2.

  8. Проверяется только собственная расчетная форма в памяти. Наличие паспорта не доказывает persistedDBданные, безопасность внешних ссылок, запуск production или реальнуюпроверку лицензии/клиентов. Резервных копий/архивов/провижининга/runtimeвызовов здесь0.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.