🔥

Тред (Дима Коваленко)


А на сегодняшний вечер я вам предлагаю увеселительный тред про всякие странные штуки в имплементации Cypress-а. Я его конечно очень люблю, но откровенно странных вещей под капотом у него ой как много. А если вы его используете, возможно вам будет даже полезно :)
notion image

Итак, приступаем! Для начала разберемся как Cypress работает. Очевидно что есть iframe, туда загружается ваше приложение и сайпресс лазит в этот iframe во время тестов.
notion image

Но! Попробуйте сделать iframe с урлой facebook.com и потом из javascript-a лазить туда и получать доступ к дому. Звучит как-то не очень нормально, согласитесь? Звучит как дыра в безопасности и так должно быть невозможно...

Да. Сайпресс это вообще по-сути одна большая война с веб-секьюрити C: Чтобы обойти это ограничение сайпресс проксирует первый запрос на ваше приложение, подменяет в ответе ему domain и ставит специальную куку. Звучит костыльненько, не так ли?

Да, и из этого следует одно из ограничений сайпресса: нельзя менять домен на лету. И теперь вы понимаете почему. Когда домен меняется изнутри страницы – мы уже не можем запроксировать запрос и увы хром блокирует доступ к тестируемому айфрейму.

Но все будет окей, если origin-ы совпадают :) То-есть если все ваши проекты находятся на одном origin-e (*.google.com) например – тесты будут работать. Кстати по этому же принципу тестируются айфреймы внутри вашего приложения.

А на самом деле у сайпресса 2 айфрейма. Во-втором загружается собранный код вашей спеки. Именно поэтому если внутри тестов вы обратитесь к document – вы не получите document приложения, а document вот этого спековского айфрейма.
notion image

Зачем так сделано? Я сам толком не знаю – не задавался вопросом :) Скорее всего чтобы изнутри тестов нельзя было взаимодействовать с самым интерфейсом сайпресса.

А еще многих интересует как работает тот самый тайм-тревелинг. На самом деле самым топорным из всех возможных способов. После каждой команды собирается снэпшот дома. Технически просто делается querySelector("*:not:(iframe)") и сохраняется в массив.

А потом когда вы кликаете на команду этот снэпшот собирается обратно в дерево дома. И тут возникает еще 1 большая проблема – сайпресс выжирает просто НЕРЕАЛЬНОЕ количество оперативной памяти.

И соответственно этой памяти есть лимит. Чем больше у вас будет тестов (а соответственно команд) – тем быстрее у вас вылетит out of memory exception. И тут совет – старайтесь делать как можно меньше тестов в 1 файле. Максимум 10-20.

Дело в том, что даже если у вас эксепшн не вылетает вы все равно от этого будете страдать. Чем больше оперативки жрет ваше приложение тем медленнее оно работает. Потому что каждый цикл GC становится все труднее и труднее. Ну и работать с маленькими спеками гораздо приятнее.

Кстати в сайпрессе у нас были спеки по 900 строк кода. В этот момент я понял что создатели инструмента не обязаны уметь идеально им пользоватся XD

Еще например в сайпрессе мне одновременно нравится и не нравится его API. Дело в том, что оно действительно выразительное и писать код в основном легко. Но этот код синхронный, а выполняется асинхронно.
notion image

Сайпресс использует собственный враппер над bluebird промисами. Если кто знаком с ФП – то работает это примерно по принципу монады Future. И все классно, но до поры до времени. Пока вам не нужно писать переиспользуемые куски кода и цепочка чейна отваливается.

И возникает вот такие магические конструкции как cy.then. Я честно сам не до конца понимаю как эта байда работает. Но короче она ожидает все пендинг чейнинги и отрабатывает в следующем тике. Но выглядит если честно как 💩
notion image

А еще очень важно понимать все технические ограничения сайпресса, обусловленные тем что он исполняется из javascript. Например команды cy.hover не существует. Потому что ховер мышкой обрабатывается на уровне ОС и запускает хренову тучу разных эффектов.

Я конечно понимаю, что после этого треда в Cypress опять мне уже не вернутся 🤓 Моя идея не разубедить вас использовать Cypress. Просто у каждой технологии есть свои недостатки – и в первую очередь вы должны узнать о них. А про плюшки вам и так расскажут в первую очередь :)

О и еще маленькая штука. Вы знали что fetch и xml http request – это АБСЛЮТНО разные вещи в браузере и хендлятся абсолютно по-разному даже на уровне ОС? Вот и я об этом узнал только из сайпресса XD