Работа с Unicode и различными кодировками в тестах на Playwright опирается на понимание, какие символы проходят через UI, API и сетевые ответы, а также каким образом браузер и тестовая среда преобразуют текстовые данные.
Браузеры давно перешли на использование UTF-8 как базовой кодировки
для HTML-документов, JavaScript-строк и DOM. Это означает, что
большинство операций в Playwright, связанных с вводом текста
(page.fill, page.type, работа с
input), автоматически поддерживают широкий диапазон
символов: кириллицу, акценты, иероглифы, эмодзи, диакритические
комбинации.
Ключевой аспект: введённая строка должна быть корректной UTF-8 последовательностью без «сломанных» суррогатов. При генерации тестовых данных важно убедиться, что строки не содержат частичных кодовых точек.
Пример ввода текста с комбинированными символами:
await page.fill('input[name="comment"]', 'Café №1 — тестирование Unicode');
Широкие символы, используемые в азиатских языках, также поддерживаются:
await page.fill('input[name="name"]', '山田太郎');
Unicode предоставляет несколько форм нормализации: NFC, NFD, NFKC и
NFKD. В веб-окружении чаще всего используются NFC и NFD. Иногда символы,
визуально идентичные, имеют разную бинарную форму. Сравнение таких строк
при проверках может приводить к ложным отрицаниям в
expect.
Для надёжных сравнений нередко применяется принудительная нормализация:
const text = await page.textContent('#title');
expect(text.normalize('NFC')).toBe(expected.normalize('NFC'));
Особенно важно при работе с диакритикой и акцентами, где один и тот же символ может быть представлен как готовый кодпоинт или как базовый символ плюс комбинирующий акцент.
Playwright позволяет перехватывать и анализировать сетевой трафик.
Ответы HTTP-запросов могут объявлять кодировку разными способами:
заголовком Content-Type, метатегом HTML или вовсе
отсутствием указания.
Для анализа тела ответа:
const [response] = await Promise.all([
page.waitForResponse(/api\/user/),
page.click('#loadUser')
]);
const buffer = await response.body();
Если сервер отдаёт данные в отличной от UTF-8 кодировке (например,
Windows-1251), требуется ручная перекодировка при помощи внешних
библиотек вроде iconv-lite. Это характерно для старых
корпоративных систем и редких API.
Преобразование:
import iconv from 'iconv-lite';
const decoded = iconv.decode(buffer, 'win1251');
В тестировании критично проверить, что после преобразования строки учитываются корректно, включая специальные символы, кавычки, валютные знаки и тональные метки.
Загрузка и скачивание файлов через Playwright
(page.waitForEvent("download")) нередко подразумевает
работу с текстовыми документами (CSV, TSV, TXT), где кодировка не всегда
UTF-8.
При открытии CSV:
const download = await page.waitForEvent('download');
await page.click('#exportCsv');
const path = await download.path();
const raw = fs.readFileSync(path);
const content = iconv.decode(raw, 'cp1251');
Важный момент: для CSV-файлов дополнительную
сложность создаёт BOM (Byte Order Mark). UTF-8-файлы с BOM
могут начинаться с EF BB BF, что ломает первую колонку при
парсинге. Перед проверкой данных BOM удаляется вручную или через
параметр в парсере.
Playwright эмулирует ввод символов через keyboard.type и
keyboard.insertText. При этом:
type симулирует нажатия клавиш.insertText напрямую вставляет строку в DOM.Для сложных Unicode-последовательностей предпочтительно
insertText, так как оно не зависит от раскладки
клавиатуры.
await page.keyboard.insertText('Český jazyk — тест с диакритикой');
В тестировании компонентов редакторов (Quill, ProseMirror, TinyMCE) требуется проверять корректность работы с комбинируемыми символами, переносами, RTL-направлением (арабский, иврит) и суррогатными парами.
Unicode вводит концепцию bidi-алгоритма для работы с RTL-языками.
HTML-атрибут dir="rtl" или CSS direction: rtl
меняют отображение. При автоматизации важно:
Получение логической строки через DOM:
const value = await page.$eval('#input', el => el.value);
Особенность: визуальные сравнения (скриншоты) часто необходимы, так как текстовые сравнения выдают одинаковые результаты при разной верстке.
Эмодзи занимают несколько кодовых точек: базовый символ плюс модификаторы (цвет кожи, гендер, вариации). Их длина в JavaScript измеряется в UTF-16 кодовых единицах, что приводит к неожиданностям. Например:
'?'.length // 2
При сравнении текста тесты должны учитывать, что DOM-методы
возвращают UTF-16 строки. Для более точного анализа используют
Array.from, интерпретирующий Unicode-графемы:
Array.from('??').length // 1
Это полезно для проверок редакторов, счётчиков символов и валидации длины ввода.
Playwright поддерживает page.screenshot и сравнение с
эталонными изображениями. Важные нюансы:
Самый надёжный подход — единая среда выполнения с установленными шрифтами и одинаковым рендерингом.
Unicode влияет на локализацию. Для проверки форматов дат, валют,
чисел используются API Intl:
const formatted = new Intl.NumberFormat('ru-RU').format(1234567.89);
В Playwright-тестах часто проверяется отображение:
Здесь Unicode регулирует не только символы, но и порядок записи.
Работа с page.request.* подразумевает передачу тела
запроса и получение JSON-ответов, которые по спецификации должны быть в
UTF-8. Однако при взаимодействии с legacy-системами встречаются
JSON-файлы в UTF-16LE или CP-1251. Прежде чем парсить, тело необходимо
декодировать, иначе JSON.parse упадёт.
Unicode-символы в логах тестов иногда приводят к искажению вывода в CI-инструментах. Особенно проблемны:
Для диагностики полезно выводить кодовые точки:
Array.from(str).map(c => c.codePointAt(0).toString(16));
Это позволяет выявить скрытые символы, влияющие на сравнение.
Windows по умолчанию использует CP-1251 или UTF-16LE в ряде инструментов, тогда как Linux и macOS ориентированы на UTF-8. При работе Playwright-тестов в CI:
Файловая система также может влиять на отображение имён файлов, содержащих сложные грэпемы, что важно при проверке загрузок.
Основные подходы:
string.length.Такая методология минимизирует ложные срабатывания в тестах и делает результаты идентичными across-platform.