我试图测试用户使用js: true
编辑问题的功能,但失败了,因为用户在测试期间没有登录(即使应该有用户会话)。
我使用Devise进行身份验证。
feature 'Authenticated User can edit own questions' do
given(:user) { create(:user) }
given(:another_user) { create(:user) }
given!(:question) { create(:question, user:) }
given!(:another_question) { create(:question, user: another_user) }
describe 'Authenticated user', js: true do
background { sign_in user } ### Here I am signing in
scenario 'can edit the question' do
visit question_path(question)
### Here save_and_open_page shows that no active session
within "#question_#{question.id}" do ### Finds turbo frame tag #question_{id}
click_on 'Edit'
fill_in 'Body', with: 'Question is edited.'
click_on 'Save'
expect(page).to_not have_content question.body
expect(page).to have_content 'Question is edited.'
expect(page).to_not have_selector 'textarea'
end
expect(page).to have_content 'Question is edited.'
end
end
end
这是我用于登录的功能助手:
def sign_in(user)
visit new_user_session_path
within 'form#new_user' do
fill_in 'Email', with: user.email
fill_in 'Password', with: user.password
click_on 'Log in'
end
end
如果我在不使用js: true
的情况下进行测试,测试工作,并且用户会话不会在测试期间的每次重定向后终止。
我使用Capybara.javascript_driver = :selenium_chrome_headless
作为js驱动程序。
3条答案
按热度按时间2uluyalo1#
这里公认的答案可能解决了这个问题,但它是一个糟糕的解决方案。“解决方案”取决于测试硬件的运行速度,因此当您迁移到云测试基础设施时,或者当您的本地机器负载很重时,可能会出现问题。该问题的根本原因是测试异步运行,需要检查页中的可见项以进行同步。在测试中,您调用'sign_in',它会填写登录页面并单击“Log In”按钮,但是没有什么等待登录的内容。因此,测试继续,并调用
visit ...
更改页面,取消浏览器提交,在登录完成和会话cookie返回之前。由于浏览器还没有会话cookie,因此用户在新页面上没有被验证。sleep(1)
通过尝试给登录时间来“修复”这个问题。在某些情况下,1秒将等待太长时间(浪费时间),而在其他情况下可能不够(片状测试)。更好的解决方案是检查页面上的更改,这表明登录已经完成总结:不要将
sleep
添加到测试中,检查页面中的更改,这些更改表明可以安全地继续前进j8ag8udp2#
实际上,您不需要每次都以这种方式登录,因为它会稍微减慢您的测试速度。我建议使用方法login_as
如果此方法不可用,请尝试在测试中包含此帮助程序(设备控制器测试):
另外,我建议在这里加上感叹号
在运行'background'之前确保用户存在
ejk8hzay3#
在我将
sleep(1)
行添加到helper后,所有测试都通过了: