Rails 5.1.3(CookieStore)下,如何通过Selenium获取浏览器会话?
嘿,我刚好碰到过类似的问题!首先得搞明白一个核心点:当Rails用:cookie_store的时候,会话数据其实是加密后存在浏览器的Cookie里的。RackTest之所以能直接拿到request.session,是因为它直接和Rails应用交互,能自动解密Cookie里的会话内容;但Selenium是模拟真实浏览器,拿到的只是加密后的Cookie字符串,没法直接解析成我们熟悉的session哈希。
不过别担心,有两种靠谱的方法能解决这个问题:
方法一:解密浏览器里的会话Cookie
Rails的会话Cookie默认叫_<你的应用名称>_session,我们可以用Rails自带的工具来解密它:
- 先通过Selenium拿到这个Cookie的value:
# 替换成你自己的会话Cookie名称 session_cookie = page.driver.browser.manage.all_cookies.find { |c| c[:name] == '_your_app_session' }[:value] - 然后用Rails的序列化工具解密:
现在decoded_session = Rails.application.config.action_dispatch.cookies_serializer.load( CGI.unescape(session_cookie), { signed: true, encrypted: true } # 这是cookie_store的默认配置,要是你改过就对应调整 )decoded_session就是和RackTest里request.session完全一样的哈希啦。
方法二:直接在测试中注入会话数据(更适合测试场景)
如果你是为了测试需要操作会话,其实没必要费劲去获取现有会话,直接生成一个加密的会话Cookie给Selenium浏览器就行:
# 先定义你要注入的会话数据 session_data = { user_id: 1, preferred_theme: 'dark' } # 用Rails工具加密成符合要求的Cookie值 encrypted_cookie = Rails.application.config.action_dispatch.cookies_serializer.dump( session_data, { signed: true, encrypted: true } ) # 把这个Cookie添加到Selenium控制的浏览器里 page.driver.browser.manage.add_cookie( name: '_your_app_session', value: CGI.escape(encrypted_cookie), domain: 'localhost', # 换成你测试环境的域名 path: '/' ) # 刷新页面后,浏览器就会带着这个会话Cookie访问应用了 page.refresh
小提醒
- 一定要确保测试环境用的
secret_key_base和Rails应用的一致,不然解密或者加密都会失败,这个配置在config/secrets.yml或者config/credentials.yml.enc里。 - 如果你改了会话Cookie的名称(比如在
config/initializers/session_store.rb里设置了key: '_my_custom_session'),记得把代码里的Cookie名称换成你自己的。
内容的提问来源于stack exchange,提问作者23tux
相关产品推荐
相关产品推荐

