ввод скриптов в текстовое поле
Ввод скриптов в текстовое поле
Что пишут в блогах
Продолжу хвастаться статусом книги.
В этом видео я показал как можно визуализировать покрытие автоматическими тестами для GraphQL api с помощью инструмента Reqover.
Cегодня хочу поговорить с вами на тему комьюнити для тестировщиков.
Как и в любой сфере, среди тестировщиков существует куча различных комьюнити. Раньше они организовывались в скайпе.
Онлайн-тренинги
Конференции
Heisenbug 2021 Moscow
Большая техническая конференция для тестировщиков
5-7 октября 2021, онлайн
Что пишут в блогах (EN)
Разделы портала
Про инструменты
Автор: Кристин Джеквони (Kristin Jackvony)
Оригинал статьи
Перевод: Ольга Алифанова
Текстовое поле в приложении кажется таким обычным делом, однако это одна из наиболее важных вещей, которую мы можем протестировать. Почему? Потому что текстовые поля дают доступ к приложению и его базе данных. Валидация текстового поля – это то, что предотвращает появление в базе плохих данных. Эти данные могут вызвать разнообразные проблемы для пользователей и разработчиков. Валидация также предотвращает атаки межсайтового скриптинга и SQL-инъекции.
Тестировать текстовое поле можно миллионами способов, и я коснусь этих способов в статье. Для начала давайте представим, что мы тестируем текстовое поле, не имея никакой информации о том, что оно делает:
Затем давайте предположим, что мы что-то знаем о том, что должно вводиться в это поле, и каковы ограничения для данных:
Для всех вышеописанных тестов выясните, какое сообщение об ошибке вы должны получать, и убедитесь, что получаете правильное сообщение.
И, наконец, нужно подумать об автоматизации. Если вы тщательно протестировали ваше поле вручную, то, возможно, нет необходимости автоматизировать все ваши тесты. Более того, большинство форм имеют более одного поля ввода, и куча тестов для каждого отдельного поля – это куча потраченного времени на прогон. Вот несколько советов, что можно автоматизировать:
Это не исчерпывающий список, а просто способ подтолкнуть вас к размышлениям о большом количестве тестов, которые можно прогнать, тестируя единственное поле. Не верьте на слово, что разработчик, создававший поле, добавил нужную валидацию, проверьте ее сами! Как-то раз я тестировала поле ввода даты, у которого было ограничение на год – он не мог быть меньше 1900 или больше, чем текущий год. Я получала нужное сообщение об ошибке, вводя 1880, но даты 1300 года легко принимались!
My WordPress Note
Рабочие заметки веб-мастера по wordpress и даже больше
WordPress: Вставка javascript в запись или страницу
Добавление записей и страниц в вордпресе не вызывает особого труда и не требует специфических знаний. В этом заслуга достаточно простых и в то же время удобных текстовых редакторов. Однако есть в них одна крайне неприятная особенность: в целях безопасности они перекодируют кавычки «» и другие используемые в скриптах знаки в специальные html-символы, что приводит к неработоспособности вставляемых java-скриптов. Да и в случаях, когда эти символы остаются на месте, скрипты все равно удивительным образом отказываются работать. От этого не спасает и переключение редактора в режим текста (HTML). В общем, внедрение javascript к себе на страницу/запись та ещё морока. Но что же делать, когда тот или иной скрипт крайне необходим на данной странице, а добиться его корректной вставки на страницу не получается? Придется придумывать обходные пути и немного изменять код используемой вами темы оформления.
Самый простой и, наверное, очевидный способ добавления javascript на сайт — добавить его в хэдер (header.php) или футер (footer.php) нашей темы оформления через редактор тем. Но как правило специфические скрипты нам нужны на определенной странице или в определенном месте в тексте записи. Поэтому данный вариант подходит только для скриптов, которые работают на всем сайте. В нашем же случае идеальным был бы вариант добавления необходимого кода в какую-то определенную область в редакторе страницы/записи, и чтобы затем этот код выводился в определенном месте на странице.
Здесь мы сталкиваемся с двумя вариантами развития событий, которые определяются условиями работы скрипта. Для примера возьму любой таймер (пусть будет один из измененных мной от timergenerator), а второй, скажем, скрипт опроса от сервиса UpToLike.ru.
Оговорюсь заранее, что в обоих случаях будут использоваться стандартные вордпресовские произвольные поля. Если у вас они не отображаются при редактировании страницы/записи, то их необходимо включить. Нажимаете «Настройки экрана» в правом верхнем углу страницы и в выехавшем окошке ставите галочку возле «Произвольные поля».
Вставка javascript-кода в
В случае с таймером, скрипт должен находиться в хэде сайта, а место отображения таймера определяется невидимым блоком
В следующий раз на новой странице это поле уже будет в списке и вам необходимо выбрать его оттуда. То есть один раз вставив своеобразную ссылку на это поле в хэдер, мы можем задавать разные коды для этого поля на разных страницах, и он будет выводится в нужном месте.
После того, как вы задали новое имя поля или выбрали уже готовое из списка, а также добавили совершенно любой текст в поле справа «Значение», нажимаете кнопку «Добавить произвольное поле», и оно перемещается вверх, где значение можно будет изменить. Как вы уже поняли, код яваскрипт необходимо будет вставлять именно в поле «Значение» напротив добавленного произвольного поля.
Допустим, что вы уже вставили необходимый код в произвольное поле и опубликовали страницу/запись. Однако Ваш код еще нигде не выводится. Чтобы это исправить необходимо зайти в редактор тем и вставить перед закрывающим тегом следующий php-код, который отвечает за вывод содержимого произвольного поля:
При этом вместо моего postcode вы должны ввести название вашего произвольного кода.
После этого можете вернуться на страницу, куда вы вставляли ваш яваскрипт-код, и просмотреть исходный код страницы (сочетание клавиш в браузере как правило ctrl+u). Если вы все сделали правильно, то перед закрывающим хэад должен стоять ваш добавленный на страницу яваскрипт-код.
При это отмечу, что таким образом можно добавлять в «голову» сайта не только яваскрипт-код, но и css-код.
Вставка javascript-кода в текст записи/страницы
Необходимость вывода определенного кода в тексте страницы у меня возникла при вставке скрипта опроса от uptolike.ru в предыдущей статье. Простой яваскрипт, который вставляется ссылкой на сайт, не требует особого шаманства. Он работает и так. А вот когда мы пытаемся вставить код, состоящий из нескольких строк, то вордпрес навязчиво пытается добавить туда свои теги перевода строк или теги абзацев, что полностью выводит вставляемый яваскрипт-код из строя. Чтобы обойти это можно использовать произвольные поля, где такого явления не наблюдается и код публикуется в его исходном виде.
Для вывода кода в тексте страницы я использую шорткоды. Это обычный текст определенного вида, который вордпрес заменит на необходимый нам код. С шорткодами вы можете столкнуться, если используете плагины вставки аудизаписей или видео на страницу.
Чтобы использовать шорткод для вставки javascript-кода на страницу необходимо добавить в конец файла темы functions.php следующий php-код:
Затем создаете произвольное поле, как я описал в предыдущем пункте и выводите его на странице в нужном месте, используя следующий шорткод:
[customscript]Имя вашего произвольного поля[/customscript]
В дальнейшем вам не нужно проводить дополнительных манипуляций. Просто создаете или выбираете произвольное поле, добавляете его и выводите с помощью шорткода.
Выразительный JavaScript: Формы и поля форм
Содержание
Я нынче ж на ученом кутеже
Твое доверье службой завоюю,
Ты ж мне черкни расписку долговую,
Чтоб мне не сомневаться в платеже.
Мефистофель, в «Фаусте» Гёте
Формы были кратко представлены в предыдущей главе в качестве способа передачи информации, введённой пользователем, через HTTP. Они были разработаны в вебе до появления JavaScript, с тем расчётом, что взаимодействие с сервером происходит при переходе на другую страницу.
Но их элементы являются частями DOM, как и остальные части страницы, а элементы DOM, представляющие поля формы, поддерживают несколько свойств и событий, которых нет у других элементов. Это делает возможным просматривать и управлять полями ввода из программ JavaScript и добавлять функциональности к классическим формам или использовать формы и поля как основу для построения приложения.
Кнопка с атрибутом type равным submit при нажатии отправляет форму. Нажатие клавиши Enter внутри поля формы имеет тот же эффект.
Отправка формы обычно означает, что браузер переходит на страницу, обозначенную в атрибуте формы action, используя либо GET либо POST запрос. Но перед этим запускается свойство “submit”. Его можно обработать в JavaScript, и обработчик может предотвратить поведение по умолчанию, вызвав на объекте event preventDefault.
Перехват событий “submit” полезен в нескольких случаях. Мы можем написать код, проверяющий допустимость введённых значений и сразу же показать ошибку вместо передачи данных формы. Или мы можем отключить отправку формы по умолчанию и дать программе возможность самой обработать ввод, например используя XMLHttpRequest для отправки данных на сервер без перезагрузки страницы.
Текстовые поля
Свойства текстовых полей selectionStart и selectionEnd содержат данные о положении курсора и выделения текста. Когда ничего не выделено, их значение одинаковое, и равно положению курсора. Например, 0 обозначает начало текста, 10 обозначает, что курсор находится после 10-го символа. Когда выделена часть поля, свойства имеют разные значения, а именно начало и конец выделенного текста. В эти поля также можно записывать значение.
К примеру, представьте, что вы пишете статью про Khasekhemwy, но затрудняетесь писать его имя правильно. Следующий код назначает тегу
Функция replaceSelection заменяет текущий выделенный текст заданным словом, и перемещает курсор на позицию после этого слова, чтобы можно было продолжать печатать.
Событие “change” для текстового поля не срабатывает каждый раз при вводе одного символа. Оно срабатывает после потери полем фокуса, когда его значение было изменено. Чтобы мгновенно реагировать на изменение текстового поля нужно зарегистрировать событие “input”, которое срабатывает каждый раз при вводе символа, удалении текста или других манипуляциях с содержимым поля.
В следующем примере мы видим текстовое поле и счётчик, показывающий текущую длину введённого текста.
Галочки и радиокнопки
Поле галочки – простой бинарный переключатель. Его значение можно извлечь или поменять через свойство checked, содержащее булевскую величину.
Тег используется для связи куска текста с полем ввода. Атрибут for должен совпадать с id поля. Щелчок по метке label включает поле ввода, оно получает фокус и меняет значение – если это галочка или радиокнопка.
Радиокнопка схожа с галочкой, но она связана с другими радиокнопками с тем же именем, так что только одна из них может быть выбрана.
Метод document.getElementsByName выдаёт все элементы с заданным атрибутом name. Пример перебирает их (посредством обычного цикла for, а не forEach, потому что возвращаемая коллекция – не настоящий массив) и регистрирует обработчик событий для каждого элемента. Помните, что у объектов событий есть свойство target, относящееся к элементу, который запустил событие. Это полезно для создания обработчиков событий – наш обработчик может быть вызван разными элементами, и у него должен быть способ получить доступ к текущему элементу, который его вызвал.
Поля select
В большинстве браузеров внешний вид поля будет отличаться от поля с единственным вариантом выбора, которое обычно выглядит как выпадающее меню.
Атрибут size тега = 0
Файловое поле
Файловое поле изначально было предназначено для закачивания файлов с компьютера через форму. В современных браузерах они также позволяют читать файлы из JavaScript. Поле работает как охранник для файлов. Скрипт не может просто взять и открыть файл с компьютера пользователя, но если тот выбрал файл в этом поле, браузер разрешает скрипту начать чтение файла.
Файловое поле обычно выглядит как кнопка с надписью вроде «Выберите файл», с информацией про выбранный файл рядом с ней.
Свойство files элемента – массивоподобный объект (не настоящий массив), содержащий список выбранных файлов. Изначально он пуст. У элемента нет простого свойства file, потому что пользователь может выбрать несколько файлов за раз при включённом атрибуте multiple.
У объектов в свойстве files есть свойства имя (имя файла), размер (размер файла в байтах), и тип (тип файла в смысле media type — text/plain или image/jpeg).
Чего у него нет, так это свойства, содержащего содержимое файла. Чтобы получить содержимое, приходится постараться. Так как чтение файла с диска занимает длительное время, интерфейс должен быть асинхронным, чтобы документ не замирал. Конструктор FileReader можно представлять себе, как конструктор XMLHttpRequest, только для файлов.
Чтение файла происходит при помощи создания объекта FileReader, регистрации обработчика события “load” для него, и вызова его метода readAsText с передачей тому файла. По окончании загрузки в свойстве result сохраняется содержимое файла.
Пример использует Array.prototype.forEach для прохода по массиву, так как в обычном цикле было бы неудобно получать нужные объекты file и reader от обработчика событий. Переменные были бы общими для всех итераций цикла.
Объекты FileReader также инициируют событие “error”, когда чтение файла не получается. Объект error будет сохранён в свойстве error. Если вы не хотите забивать голову ещё одной неудобной асинхронной схемой, вы можете обернуть её в обещание (см. главу 17):
Возможно читать только часть файла, вызывая slice и передавая результат (т.н. объект blob) объекту reader.
Хранение данных на стороне клиента
Простые HTML-странички с добавкой JavaScript могут выступать отличной основой для мини-приложений – небольших вспомогательных программ, автоматизирующих ежедневные дела. Присоединив к полям формы обработчики событий вы можете делать всё – от конвертации фаренгейтов в цельсии до генерации паролей из основного пароля и имени веб-сайта.
Когда такому приложению нужно сохранять информацию между сессиями, переменные JavaScript использовать не получится – их значения выбрасываются каждый раз при закрытии страницы. Можно было бы настроить сервер, подсоединить его к интернету и тогда приложение хранило бы ваши данные там. Это мы разберём в главе 20. Но это добавляет вам работы и сложности. Иногда достаточно хранить данные в своём браузере. Но как?
Можно хранить строковые данные так, что они переживут перезагрузку страниц — для этого надо положить их в объект localStorage. Он разрешает хранить строковые данные под именами (которые тоже являются строками), как в этом примере:
Переменная в localStorage хранится, пока её не перезапишут, удаляется при помощи removeItem или очисткой локального хранилища пользователем.
У сайтов с разных доменов – разные отделения в этом хранилище. То есть, данные, сохранённые с вебсайта в localStorage, могут быть прочтены или перезаписаны только скриптами с этого же сайта.
Также браузеры ограничивают объём хранимых данных, обычно в несколько мегабайт. Это ограничение, вкупе с тем фактом, что забивание жёстких дисков у людей не приносит прибыли, предотвращает отъедание места на диске.
Следующий код реализует простую программу для ведения заметок. Она хранит заметки в виде объекта, ассоциируя заголовки с содержимым. Он кодируется в JSON и хранится в localStorage. Пользователь может выбрать записку через поле новая
Скрипт инициализирует переменную notes значением из localStorage, а если его там нет – простым объектом с одной пустой записью «что купить». Попытка прочесть отсутствующее поле из localStorage вернёт null. Передача null в JSON.parse заставит его проанализировать строку «null» и вернуть null обратно. Поэтому для значения по умолчанию можно использовать оператор ||.
Когда данные в note меняются (добавляется новая запись или меняется текущая), для обновления хранимого поля вызывается функция saveToStorage. Если б мы рассчитывали, что у нас будут храниться тысячи записей, это было бы слишком накладно, и нам пришлось бы придумать более сложную процедуру для хранения – например, своё поле для каждой записи.
Когда пользователь добавляет запись, код должен обновить текстовое поле, хотя у поля и есть обработчик “change”. Это нужно потому, что событие “change” происходит, только когда пользователь меняет значение поля, а не когда это делает скрипт.
Есть ещё один похожий на localStorage объект под названием sessionStorage. Разница между ними в том, что содержимое sessionStorage забывается по окончанию сессии, что для большинства браузеров означает момент закрытия.
HTML предоставляет множество различных типов полей формы – текстовые, галочки, множественного выбора, выбора файла.
Из JavaScript можно получать значение и манипулировать этими полями. По изменению они запускают событие “change”, по вводу с клавиатуры – “input”, и ещё много разных клавиатурных событий. Они помогают нам отловить момент, когда пользователь взаимодействует с полем ввода. Свойства вроде value (для текстовых полей и select) или checked (для галочек и радиокнопок) используются для чтения и записи содержимого полей.
Когда пользователь выбрал файл в своей локальной файловой системе через поле выбора файла, интерфейс FileReader позволит нам добраться до содержимого файла из программы JavaScript.
Объекты localStorage и sessionStorage можно использовать для хранения информации таким способом, который переживёт перезагрузку страницы. Первый сохраняет данные навсегда (ну или пока пользователь специально не сотрёт их), а второй – до закрытия браузера.
Упражнения
Верстак JavaScript
Сделайте интерфейс, позволяющий писать и исполнять кусочки кода JavaScript.
Сделайте кнопку рядом с Поехали
Автодополнение
Дополните текстовое поле так, что при вводе текста под ним появлялся бы список вариантов. У вас есть массив возможных вариантов, и показывать нужно те из них, которые начинаются с вводимого текста. Когда пользователь щёлкает по предложенному варианту, он меняет содержимое поля на него.
Игра «Жизнь» Конвея
Это простая симуляция жизни на прямоугольной решётке, каждый элемент которой живой или нет. Каждое поколение (шаг игры) применяются следующие правила:
— каждая живая клетка, количество живых соседей которой меньше двух или больше трёх, погибает;
— каждая живая клетка, у которой от двух до трёх живых соседей, живёт до следующего хода;
— каждая мёртвая клетка, у которой есть ровно три живых соседа, оживает.
Соседи клетки – это все соседние с ней клетки по горизонтали, вертикали и диагонали, всего 8 штук.
Обратите внимание, что правила применяются ко всей решётке одновременно, а не к каждой из клеток по очереди. То есть, подсчёт количества соседей происходит в один момент перед следующим шагом, и изменения, происходящие на соседних клетках, не влияют на новое состояние клетки.
Самые простые и эффективные способы тестирования поля ввода текста
Любое текстовое поле в создаваемом программном обеспечении кажется таким простым и понятным функционалом, что процесс тестирования сводится к банальной проверке правильности его заполнения. Но, это только на первый взгляд.
Проверять правильность работы текстового поля нужно с особой тщательностью, ведь с его помощью можно очень быстро получить несанкционированный доступ к базе данных!
Процесс валидации текстовой формы при функциональном тестировании – это первая среди всех проверок, которая поможет предотвратить манипуляции с пользовательскими файлами и данными. Также это своего рода защита перед появлением в БД вредной информации.
Подобные вирусные файлы могут вызвать проблемы с функционированием веб-продукта как на стороне клиента, так и на стороне сервера. Ну и наконец, корректная валидация позволяет сразу же предотвратить атаки межсайтового скриптинга и вредоносных SQL-инъекций хакеров.
Основные типы проверки текстового поля
Проверять работоспособность текстового поля можно очень многими способами. Мы выделим наиболее важные проверки, которые QA-специалист должен выполнять в обязательном порядке при тестировании текстовых полей.
Тестирование форм без спецификации
Итак, представим, что необходимо проверить текстовое поле, о котором нет особой информации в спецификации на проекте.
В подобной ситуации можно выполнить следующие проверки:
Проверка полей на основе технической документации
Представим, что мы кое-что знаем о формах, знаем какие примерные значения можно вводить в форму, а также каковы ограничения в них установлены.
Тестирование поля с известными данными
Итак, что мы можем конкретного проверить:
Для всего вышеизложенного перечня проверок стоит выяснить, какие именно сообщения об ошибке отображаются и убедится в том, что все сообщения при валидной отправке тоже корректны.
Тестирование текстовых полей + автоматизация
Без автоматизации тестирования в данном случае тоже никак не обойтись.
Если тестировщик выполнил полный перечень ручных проверок, скорее всего нет надобности в автоматизации тестов. Более того, множество форм состоит из нескольких полей, а значит масса тестов для каждого по отдельности – это огромное количество потраченного времени на их выполнение.
Тем не менее, целесообразной будет автоматизация следующих пунктов:
Конечно же, это неполный перечень того, что можно тестировать при проверке форм. Но данный список можно использовать как базовый набор проверок, которые стоит в обязательном порядке выполнять при работе с текстовыми формами.
Тестировщик никогда не должен верить разработчику на слово, что все и так работает, и незачем лишний раз себя утруждать монотонными проверками. Ведь при нахождении клиентом технической уязвимости, спросят в первую очередь именно с проверяющего!
Проверка заполнения формы с использованием JavaScript
Данный урок описывает, как создать JavaScript форму, которая проверяет правильность заполнения посетителем полей перед отправкой данных на сервер. Сначала мы объясним, почему проверка заполнения формы является полезной методикой, а затем построим простой пример с объяснением, как все происходит.
Зачем нужна проверка заполнения формы?
Существует два основных метода для проверки заполнения формы: на стороне сервера (с использованием CGI скриптов, ASP и т.д.) и на стороне клиента (обычно используется JavaScript). Проверка на стороне сервера более безопасная, но в большинстве случаев требует более сложного кода, в то время как проверка на стороне клиента выполняется проще и быстрее (браузер не нуждается в соединении с сервером для проверки заполнения формы, таким образом, пользователь получает немедленный ответ в случае пропущенных полей, которые необходимо заполнить).
Проверка формы на стороне клиента. Обычно выполняется с помощью встроенного JavaScript скрипта.
Проверка формы на стороне сервера. Обычно выполняется с помощью CGI или ASP скрипта.
В данном уроке мы построим простую форму с проверкой на стороне клиента с помощью JavaScript. Вы сможете затем адаптировать ее под свои нужды.
Простая форма с проверкой.
Давайте построим простую форму с проверкой заполнения с помощью скрипта. Данная форма имеет одно текстовое поле «Ваше имя» и кнопку для отправки данных. Наш скрипт проверяет, что пользователь ввел свое имя перед тем, как отправить данные на сервер.
Откройте форму и посмотрите в действии. Попробуйте нажать кнопку «Отправить данные» ничего не вводя в поле «Ваше имя».
Вы также можете открыть исходный код формы в другом окне, чтобы было удобно работать с уроком.
Страница содержит функцию JavaScript, которая называется validate_form(). Она выполняет проверку заполнения формы. давайте посмотрим сначала на форму.
Форма
Функция validate_form()
Функция проверки формы validate_form() встроена в секцию head вначале страницы: