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

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

Но! Попробуйте сделать iframe с урлой facebook.com и потом из javascript-a лазить туда и получать доступ к дому.
Звучит как-то не очень нормально, согласитесь? Звучит как дыра в безопасности и так должно быть невозможно...
Да. Сайпресс это вообще по-сути одна большая война с веб-секьюрити C:
Чтобы обойти это ограничение сайпресс проксирует первый запрос на ваше приложение, подменяет в ответе ему
domain
и ставит специальную куку.
Звучит костыльненько, не так ли?Да, и из этого следует одно из ограничений сайпресса: нельзя менять домен на лету.
И теперь вы понимаете почему. Когда домен меняется изнутри страницы – мы уже не можем запроксировать запрос и увы хром блокирует доступ к тестируемому айфрейму.
Но все будет окей, если origin-ы совпадают :) То-есть если все ваши проекты находятся на одном origin-e (*.google.com) например – тесты будут работать.
Кстати по этому же принципу тестируются айфреймы внутри вашего приложения.
А на самом деле у сайпресса 2 айфрейма. Во-втором загружается собранный код вашей спеки.
Именно поэтому если внутри тестов вы обратитесь к document – вы не получите document приложения, а document вот этого спековского айфрейма.

Зачем так сделано? Я сам толком не знаю – не задавался вопросом :)
Скорее всего чтобы изнутри тестов нельзя было взаимодействовать с самым интерфейсом сайпресса.
А еще многих интересует как работает тот самый тайм-тревелинг. На самом деле самым топорным из всех возможных способов.
После каждой команды собирается снэпшот дома. Технически просто делается querySelector("*:not:(iframe)") и сохраняется в массив.
А потом когда вы кликаете на команду этот снэпшот собирается обратно в дерево дома.
И тут возникает еще 1 большая проблема – сайпресс выжирает просто НЕРЕАЛЬНОЕ количество оперативной памяти.
И соответственно этой памяти есть лимит. Чем больше у вас будет тестов (а соответственно команд) – тем быстрее у вас вылетит out of memory exception.
И тут совет – старайтесь делать как можно меньше тестов в 1 файле. Максимум 10-20.
Дело в том, что даже если у вас эксепшн не вылетает вы все равно от этого будете страдать. Чем больше оперативки жрет ваше приложение тем медленнее оно работает. Потому что каждый цикл GC становится все труднее и труднее.
Ну и работать с маленькими спеками гораздо приятнее.
Кстати в сайпрессе у нас были спеки по 900 строк кода.
В этот момент я понял что создатели инструмента не обязаны уметь идеально им пользоватся XD
Еще например в сайпрессе мне одновременно нравится и не нравится его API. Дело в том, что оно действительно выразительное и писать код в основном легко.
Но этот код синхронный, а выполняется асинхронно.

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

А еще очень важно понимать все технические ограничения сайпресса, обусловленные тем что он исполняется из javascript.
Например команды cy.hover не существует. Потому что ховер мышкой обрабатывается на уровне ОС и запускает хренову тучу разных эффектов.
Я конечно понимаю, что после этого треда в Cypress опять мне уже не вернутся 🤓
Моя идея не разубедить вас использовать Cypress. Просто у каждой технологии есть свои недостатки – и в первую очередь вы должны узнать о них.
А про плюшки вам и так расскажут в первую очередь :)
О и еще маленькая штука. Вы знали что fetch и xml http request – это АБСЛЮТНО разные вещи в браузере и хендлятся абсолютно по-разному даже на уровне ОС?
Вот и я об этом узнал только из сайпресса XD