require "test_helper" require "socket" class ApplicationSystemTestCase < ActionDispatch::SystemTestCase DEFAULT_VIEWPORT_WIDTH = 1400 DEFAULT_VIEWPORT_HEIGHT = 1400 setup do Capybara.default_max_wait_time = 5 if ENV["SELENIUM_REMOTE_URL"].present? server_port = ENV.fetch("CAPYBARA_SERVER_PORT", 30_000 + (Process.pid % 1000)).to_i app_host = ENV["CAPYBARA_APP_HOST"].presence || IPSocket.getaddress(Socket.gethostname) Capybara.server_host = "0.0.0.0" Capybara.server_port = server_port Capybara.always_include_port = true Capybara.app_host = "http://#{app_host}:#{server_port}" end reset_viewport end if ENV["SELENIUM_REMOTE_URL"].present? Capybara.register_driver :selenium_remote_chrome do |app| options = Selenium::WebDriver::Chrome::Options.new options.add_argument("--window-size=1400,1400") Capybara::Selenium::Driver.new( app, browser: :remote, url: ENV["SELENIUM_REMOTE_URL"], capabilities: options ) end driven_by :selenium_remote_chrome, screen_size: [ 1400, 1400 ] else requested_browser = ENV["E2E_BROWSER"].presence&.to_sym local_browser = case requested_browser when :headless_chrome then :chrome when :headless_firefox then :firefox else requested_browser || :chrome end headless = ENV["CI"].present? || requested_browser.in?([ :headless_chrome, :headless_firefox ]) || ENV["DISPLAY"].blank? Capybara.register_driver :selenium_local_chrome do |app| options = case local_browser when :firefox Selenium::WebDriver::Firefox::Options.new.tap do |firefox_options| firefox_options.add_argument("--width=1400") firefox_options.add_argument("--height=1400") firefox_options.add_argument("-headless") if headless end else Selenium::WebDriver::Chrome::Options.new.tap do |chrome_options| chrome_options.add_argument("--window-size=1400,1400") chrome_options.add_argument("--headless=new") if headless chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") end end Capybara::Selenium::Driver.new( app, browser: local_browser, options: options ) end driven_by :selenium_local_chrome, screen_size: [ 1400, 1400 ] end def teardown reset_viewport super end private def reset_viewport page.current_window.resize_to(DEFAULT_VIEWPORT_WIDTH, DEFAULT_VIEWPORT_HEIGHT) if page&.current_window end def sign_in(user) visit new_session_path within %(form[action='#{sessions_path}']) do fill_in "Email", with: user.email fill_in "Password", with: user_password_test click_on "Log in" end # Trigger Capybara's wait mechanism to avoid timing issues with logins find("h1", text: "Welcome back, #{user.first_name}") end def login_as(user) sign_in(user) end def sign_out find("#user-menu").click click_button "Logout" # Trigger Capybara's wait mechanism to avoid timing issues with logout find("a", text: "Sign in") end def within_testid(testid) within "[data-testid='#{testid}']" do yield end end # Interact with DS::Select custom dropdown components. # DS::Select renders as a button + listbox — not a native