我正在尝试使用RSpec Capybara和selenium-chrome驱动程序在Rails上运行集成测试。
我也在使用capybara-angular宝石。
我对到底发生了什么感到有些困惑,因为当我睡觉时我的rspec测试没有看到脚本时,请检查chrome调试器中的“ sources”选项卡,尽管它似乎没有加载我的资产确实会因为页面被隐藏而使ng-if语句正常工作。
所以我不太确定发生了什么。该页面可以按预期在开发中正常工作,但是$ scope上的变量未在测试中设置。
这是我在“ system.rb
中设置的 RSpec.configure do |config|
config.before(:each, type: :system) do
driven_by :rack_test
end
config.before(:each, type: :system, js: true) do
driven_by :selenium_chrome
end
end
require "capybara-screenshot/rspec"
include Capybara::Angular::DSL
这是我正在运行的测试:
it "shows changes to the budget when the budget is changed", :js do
visit(root_path)
sleep 0.5
fill_in "inputEmail", with: "test@tester.com"
fill_in "password", with: "test"
click_on("Log In")
sleep 0.25
click_on("Budgeting")
sleep 10
expect(page).to have_selector("#current_project_name", text: "Project A")
expect(page).to have_selector("#budgetInput1")
fill_in "#budgetInput1", with: "100"
# Fail on next line with 'expected to find visible css "#budgetInput1" but there were no matches'
page.should have_selector("#budgetInput1", text: "100") # <--test fails with
end
据我所知,未找到它的原因是因为该元素出现在带有ng-if="showBudget"
的div中。 $scope.showBudget=true
已在控制器中设置,但控制器似乎未加载,{{showBudget==unknown}}
返回了true
,这表明AngularJS正在加载,但页面清单所加载的脚本不是。
如何解决此问题?
答案 0 :(得分:0)
您似乎没有使用正确的期望值。由于您可以在ID为fill_in
的元素上调用budgetInput1
,因此期望(不确定为什么要混合expect
和should
语法)与{{1 }}选项不起作用。您可能想要的是
text
如果相反,您期望expect(page).to have_field('budgetInput1', with: '100')
触发页面上的更新,将页面ID为“ budgetInput1”的输入元素替换为其他元素,那么您可能需要发送回车,制表符,或在初始元素之外单击以触发更改。
另一方面,我不确定测试中为什么有睡眠-fill_in
将等待匹配元素的存在,因此,在致电visit之后,真的应该不需要睡眠半秒钟-对于10秒钟的睡眠(您的应用确实需要10秒钟的响应时间吗?),您可以只使用fill_in
上的wait选项,以便在元素存在时立即继续测试,而不是等待全部10秒,如果没有必要。
答案 1 :(得分:0)
问题原来与我想的有些不同。当我查看“源”选项卡时,在开发中,我使用了一大堆文件,包括清单中列出的所有内容。在水豚测试中,所有这些文件(包括jquery和angular)都串联到一个文件中。 jQuery在顶部,在底部,大约是40000行,这是我的角度控制器文件。问题在于它创建的文件不是基于我的JavaScript资产的最新版本。
override func viewDidLoad() {
super.viewDidLoad()
parseData(noOfPosts:90)
TableView.delegate = self
TableView.dataSource = self
TableView.tableFooterView = UIView()
let myTop2Constraint:NSLayoutConstraint = TableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 50)
let myBtm2Constraint:NSLayoutConstraint = TableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 50)
myTop2Constraint.isActive = true
myBtm2Constraint.isActive = true
if(UIDevice.current.orientation.isLandscape){
myTop2Constraint.isActive = false
myBtm2Constraint.isActive = false
}
}
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
let myTop2Constraint:NSLayoutConstraint = TableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 50)
let myBtm2Constraint:NSLayoutConstraint = TableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 50)
let myTopConstraint:NSLayoutConstraint = TableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0)
let myBtmConstraint:NSLayoutConstraint = TableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0)
myTopConstraint.isActive = false
myBtmConstraint.isActive = false
myTop2Constraint.isActive = false
myBtm2Constraint.isActive = false
if(UIDevice.current.orientation.isLandscape){
self.catIsuSemasa.isHidden = true
self.catOthers.isHidden = true
self.catSocial.isHidden = true
self.catPolitics.isHidden = true
if(myTop2Constraint.isActive){
print("error1?")
myTop2Constraint.isActive = false
print("error2?")
myBtm2Constraint.isActive = false
print("error3?")
myTopConstraint.isActive = true
myBtmConstraint.isActive = true
}else{
TableView.removeAllConstraints()
myTopConstraint.isActive = true
myBtmConstraint.isActive = true
}
}else{
self.catIsuSemasa.isHidden = false
self.catOthers.isHidden = false
self.catSocial.isHidden = false
self.catPolitics.isHidden = false
if(myTopConstraint.isActive){
print("error")
myTopConstraint.isActive = false
print("error2")
myBtmConstraint.isActive = false
print("error3")
myTop2Constraint.isActive = true
print("error4")
myBtm2Constraint.isActive = true
print("run?")
}
}
}
extension UIView {
func removeAllConstraints() {
self.removeConstraints(self.constraints)
for view in self.subviews {
view.removeAllConstraints()
}
}
}
这在开发中通常不是必需的,我在js文件中所做的更改会立即被获取,但是我猜想在使用硒铬运行Capybara测试时这是必需的。