Rails 7.1, системные тесты на Selenium с headless Chrome. Один тест на форму заказа падает в CI примерно в каждом четвёртом прогоне, локально я прогнала его 50 раз подряд без единого падения. Падает в конце:
click_on "Оформить"
sleep 1
expect(page.text).to include("Заказ создан")
expect(Order.last.status).to eq("new")
sleep уже стоит, пробовала 2 секунды, стало реже, но не прошло. CI слабее моего ноутбука, это понятно, но не ставить же пять.
Тут две беды сразу. sleep ничего не гарантирует: на быстрой машине он тратит время зря, на медленной его не хватает. А page.text берёт текст страницы в эту самую секунду и не ждёт. Матчеры Capybara сами повторяют проверку, пока не выйдет default_max_wait_time:
click_on "Оформить"
expect(page).to have_content("Заказ создан")
expect(page).to have_css(".order-status", text: "Новый")
Никакого sleep. Если стандартных 2 секунд ожидания в CI мало, лучше поднять Capybara.default_max_wait_time до 5 для всех: на зелёном прогоне ожидание всё равно заканчивается, как только текст появился. А Order.last сразу после клика это вторая частая причина таких падений: браузер и тест живут в разных потоках, и запрос мог ещё не дойти до базы. Проверяйте то, что видит пользователь.
Со стороны CI проверьте ещё, сколько процессов гоняется на одном раннере. 8 воркеров на 4 ядра дают флаки по всему набору, а не в одном тесте
и посмотрите скриншоты падений, Rails сам кладёт их в tmp/screenshots. только сохраните эту папку как артефакт CI
Убрала sleep, переписала на have_content, а Order.last заменила на проверку статуса на странице, как советовали. На скриншотах упавших прогонов, кстати, и правда крутился спиннер: ответ в CI иногда шёл дольше секунды, только и всего. Прогнала 30 раз подряд, всё зелёное, и тест стал быстрее на секунду. Про воркеры на раннере передала админам.