- Изменением стиля
- Как это правильно делается в Cypress
- Внутри браузера
- jQuery
- Fluent chain
- Итоговое сравнение
- А также
Подсветка изменением стиля
Видел в Линкедине пост о том как выделить веб-элемент и сделать скриншот страницы с помощью тест-раннеров Selenium и Playwright.
Другой человек сделал похожее в Playwright:
В обоих случаях мы выделяем элемент, изменяя его стиль. Можно сделать такое выделение на любой странице, просто открыв DevTools и изменив style
-объект нужного элемента.
Смотрите, как я настраиваю границы поля ввода в отличном (но малопопулярном) поисковике Ecosia:
В Cypress
Как я это делаю в Cypress.
cypress/e2e/spec.cy.js :
it('highlights the input element', () => { cy.visit('/') cy.get('input[aria-label="Search the web"]').then(($el) => { $el[0].style.border = '3px solid red' }) cy.screenshot('input-highlighted', { overwrite: true, clip: { x: 0, y: 0, width: 1200, height: 1000 }, }) })
🎁 Полный код — в моем репозитории bahmutov/highlight-element-example.
Несколько замечаний об этом тесте:
- Базовый url задается в файле
cypress.config.js
, поэтому в тесте я могу просто зайти на корень командойcy.visit('/')
- Команды запросов в Cypress (типа cy.get) выдают jQuery-объект, если элемент найден. Здесь я просто использовал DOM-элемент
$el[0].style = ...
- Я обрезал скриншот, полученный командой cy.screenshot, потому что домашняя страница Ecosia очень большая, а нам сейчас интересен только этот элемент ввода.
Выполнение кода в браузере
Раннер Cypress имеет особенности. Тесты в Selenium и Playwright выполняются в окружении Node.js, отправляя команды «получить элемент», «снять скриншот» в браузер по определенному протоколу.
А тесты в Cypress запускаются внутри браузера. Таким образом, тебе не нужно «инжектировать» JavaScript, который посылает строки кода из Node.js. Даже можно использовать локальные переменные, регистрировать коллбэки и т. д. — это все делается из теста. Не нужно преобразование типов аргументов, не нужна сериализация.
// нормальный тестовый код Cypress, тоже работает const border = '3px solid red' cy.get('input[aria-label="Search the web"]').then(($el) => { $el[0].style.border = border })
jQuery
Cypress по умолчанию «заворачивает» все найденные элементы в объект jQuery. Это упрощает применение многочисленных методов jQuery работы с элементами DOM. Например, можно задать сразу несколько CSS-свойств:
const border = '3px solid red' cy.get('input[aria-label="Search the web"]').then(($el) => { $el.css({ background: 'yellow', border, }) })
Fluent chain
В приведенном выше тесте мы получаем элемент, который тест передает следующей команде:
cy.get(...) .then($el => { $el.css(...) })
Внутри коллбэка cy.then
тест вызывает метод «css
» — и всё. Можно вызывать метод по его имени и передавать аргументы встроенной командой Cypress cy.invoke.
const border = '3px solid red' cy.get('input[aria-label="Search the web"]').invoke('css', { background: 'yellow', border, })
Работает точно так же.
Это прекрасно, потому что в Cypress есть типы TypeScript — и когда я пишу cy.get(...).invoke(...)
, редактор кода подхватывает доступные методы jQuery, которые можно вызвать по этому объекту.
Чудесно, да?
Сравнение
Так какое решение лучше?
А также
Написал небольшой плагин cypress-highlight:
// Выделить все элементы с тестовыми атрибутами import { highlight } from 'cypress-highlight' it('loads an app', () => { cy.visit('/') highlight() }) // Выделить только нужные селекторы highlight('[data-test-id]', '.testable')
Глеб Бахмутов — VP of Engineering в Cypress.io