WYSIWYG (What You See Is What You Get) редакторы предоставляют пользователю визуальный интерфейс для работы с контентом, скрывая HTML-код и предоставляя средства редактирования текста, форматирования и вставки медиа. Тестирование таких редакторов требует специфического подхода, так как взаимодействие с визуальным контентом отличается от обычных форм и полей ввода.
Для работы с редактором нужно корректно настроить окружение. Обычно редакторы интегрируются через iframe или shadow DOM, что требует дополнительных техник для взаимодействия.
// Пример команды для получения body внутри iframe
Cypress.Commands.add('getIframeBody', (iframeSelector) => {
return cy
.get(iframeSelector)
.its('0.contentDocument.body')
.should('not.be.empty')
.then(cy.wrap);
});
Использование команды getIframeBody позволяет безопасно
обращаться к элементам внутри редактора, как если бы они находились в
обычном DOM.
Простейший сценарий — ввод и проверка текста. В WYSIWYG редакторах
необходимо учитывать, что текст может быть обёрнут тегами
<p>, <span> или
<strong> в зависимости от форматирования.
cy.getIframeBody('#editor-iframe')
.clear()
.type('Тестирование Cypress')
.should('contain.text', 'Тестирование Cypress');
Важно использовать contain.text, а не
have.value, так как поле редактора обычно не является
<input>.
Форматирование, такое как жирный, курсив, списки или ссылки, тестируется через имитацию клика на соответствующие кнопки панели инструментов и проверку изменения DOM внутри редактора.
cy.get('#bold-button').click();
cy.getIframeBody('#editor-iframe')
.type('Жирный текст')
.find('strong')
.should('contain.text', 'Жирный текст');
Для списков:
cy.get('#unordered-list-button').click();
cy.getIframeBody('#editor-iframe')
.type('Элемент списка{enter}')
.find('li')
.should('contain.text', 'Элемент списка');
Вставка изображений и видео требует проверки как визуального
отображения, так и атрибутов, например src для
изображений.
cy.get('#insert-image-button').click();
cy.get('#image-url-input').type('https://example.com/image.png{enter}');
cy.getIframeBody('#editor-iframe')
.find('img')
.should('have.attr', 'src', 'https://example.com/image.png');
Проверка наличия медиа внутри редактора помогает убедиться, что контент корректно отображается пользователю.
Современные редакторы поддерживают автосохранение и триггеры событий при изменении текста. В Cypress это можно проверить через перехват сетевых запросов или проверку состояния приложения.
cy.intercept('POST', '/api/save').as('save');
cy.getIframeBody('#editor-iframe')
.type('Сохранение тест')
cy.wait('@save').its('response.statusCode').should('eq', 200);
Такой подход позволяет убедиться, что изменения действительно сохраняются на сервере.
Редакторы обычно поддерживают комбинации клавиш для отмены и повторения действий. В Cypress можно эмулировать нажатия клавиш:
cy.getIframeBody('#editor-iframe')
.type('Текст для undo{ctrl+z}');
cy.getIframeBody('#editor-iframe')
.should('not.contain.text', 'Текст для undo');
cy.getIframeBody('#editor-iframe')
.type('{ctrl+y}');
cy.getIframeBody('#editor-iframe')
.should('contain.text', 'Текст для undo');
Использование {ctrl+z} и {ctrl+y} позволяет
имитировать поведение стандартного редактора и проверять корректность
работы истории изменений.
Работа с выделением текста в WYSIWYG редакторах также требует взаимодействия с iframe и методами Cypress для имитации мыши:
cy.getIframeBody('#editor-iframe')
.type('Выделяемый текст');
cy.getIframeBody('#editor-iframe')
.find('p')
.trigger('mousedown')
.trigger('mousemove', { clientX: 50, clientY: 0 })
.trigger('mouseup')
.then(($p) => {
const selectedText = window.getSelection().toString();
expect(selectedText).to.eq('Выделяемый текст');
});
Проверка выделения позволяет убедиться, что текст реагирует на стандартные действия пользователя.
При тестировании важно предусматривать:
cy.getIframeBody('#editor-iframe')
.invoke('html', '<script>alert("xss")</script>')
.should('not.contain.html', '<script>alert("xss")</script>');
Это предотвращает уязвимости и гарантирует стабильность интерфейса.
Для крупных проектов рекомендуется создавать кастомные команды Cypress для всех повторяющихся действий: ввод текста, форматирование, вставка медиа, проверка содержимого. Это упрощает написание тестов и делает их более читабельными.
Cypress.Commands.add('typeInEditor', (iframeSelector, text) => {
cy.getIframeBody(iframeSelector).clear().type(text);
});
Использование таких команд сокращает дублирование кода и обеспечивает единый подход ко всем сценариям работы с WYSIWYG редакторами.