-
-
Notifications
You must be signed in to change notification settings - Fork 93
/
spec_helper.rb
146 lines (124 loc) · 6.08 KB
/
spec_helper.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# frozen_string_literal: true
require "bundler/setup"
require "rspec"
PROJECT_ROOT = File.expand_path("..", __dir__)
%w[/lib /spec].each { |p| $LOAD_PATH.unshift(p) }
require "fileutils"
require "shellwords"
require "capybara/spec/spec_helper"
require "capybara/cuprite"
require "support/test_app"
require "support/external_browser"
puts ""
command = Ferrum::Browser::Command.build(Ferrum::Browser::Options.new, nil)
puts `#{Shellwords.escape(command.path)} --version`
puts ""
Capybara.save_path = File.join(PROJECT_ROOT, "spec", "tmp", "save_path")
Capybara.register_driver(:cuprite) do |app|
options = {}
options.merge!(inspector: true) if ENV["INSPECTOR"]
options.merge!(logger: StringIO.new) if ENV["CI"]
options.merge!(headless: false) if ENV["HEADLESS"] == "false"
Capybara::Cuprite::Driver.new(app, options)
end
module TestSessions
Cuprite = Capybara::Session.new(:cuprite, TestApp)
end
RSpec.configure do |config|
config.define_derived_metadata do |metadata|
regexes = <<~REGEXP.split("\n").map { |s| Regexp.quote(s.strip) }.join("|")
node #obscured?
node #drag_to should work with jsTree
node #drag_to should drag and drop an object
node #drag_to should drag and drop if scrolling is needed
node #drag_to should drag a link
node #drag_to should work with Dragula
node #drag_to HTML5 should work with SortableJS
node #drag_to HTML5 should HTML5 drag and drop an object
node #drag_to HTML5 should set clientX/Y in dragover events
node #drag_to HTML5 should not HTML5 drag and drop on a non HTML5 drop element
node #drag_to HTML5 should HTML5 drag and drop when scrolling needed
node #drag_to HTML5 should drag HTML5 default draggable elements
node #drag_to HTML5 should drag HTML5 default draggable element child
node #drag_to should simulate a single held down modifier key
node #drag_to should simulate multiple held down modifier keys
node #drag_to should support key aliases
node #drag_to HTML5 should preserve clientX/Y from last dragover event
node #drag_to HTML5 should simulate a single held down modifier key
node #drag_to HTML5 should simulate multiple held down modifier keys
node #drag_to HTML5 should support key aliases
node #drag_to HTML5 should trigger a dragenter event, before the first dragover event
node Element#drop can drop a file
node Element#drop can drop multiple files
node Element#drop can drop strings
node Element#drop can drop multiple strings
node Element#drop can drop a pathname
node #visible? details non-summary descendants should be non-visible
node #visible? works when details is toggled open and closed
node #path reports when element in shadow dom
node #shadow_root
node #set should submit single text input forms if ended with
#all with obscured filter should only find nodes on top in the viewport when false
#all with obscured filter should not find nodes on top outside the viewport when false
#all with obscured filter should find top nodes outside the viewport when true
#all with obscured filter should only find non-top nodes when true
#fill_in should fill in a color field
#fill_in should handle carriage returns with line feeds in a textarea correctly
#has_field with valid should be false if field is invalid
#find with spatial filters should find an element above another element
#find with spatial filters should find an element below another element
#find with spatial filters should find an element left of another element
#find with spatial filters should find an element right of another element
#find with spatial filters should combine spatial filters
#find with spatial filters should find an element "near" another element
#has_css? with spatial requirements accepts spatial options
#has_css? with spatial requirements supports spatial sugar
#fill_in should fill in a textarea in a reasonable time by default
#has_element? should be true if the given element is on the page
REGEXP
intentional_skip = <<~REGEXP.split("\n").map { |s| Regexp.quote(s.strip) }.join("|")
Capybara::Session Cuprite #reset_session! closes extra windows
REGEXP
metadata[:skip] = true if metadata[:full_description].match(/#{regexes}/)
metadata[:skip] = "Intentionally skipped" if metadata[:full_description].match(/#{intentional_skip}/)
metadata[:skip] = true if metadata[:requires]&.include?(:active_element)
end
config.around do |example|
remove_temporary_folders
if ENV.fetch("CI", nil)
session = @session || TestSessions::Cuprite
session.driver.browser.options.logger.truncate(0)
session.driver.browser.options.logger.rewind
end
example.run
if ENV.fetch("CI", nil) && example.exception
session = @session || TestSessions::Cuprite
save_exception_artifacts(session.driver.browser, example.metadata)
end
end
Capybara::SpecHelper.configure(config)
def save_exception_artifacts(browser, meta)
filename = File.basename(meta[:file_path])
line_number = meta[:line_number]
timestamp = Time.now.strftime("%Y-%m-%dT%H-%M-%S-%N")
save_exception_log(browser, filename, line_number, timestamp)
save_exception_screenshot(browser, filename, line_number, timestamp)
end
def save_exception_screenshot(browser, filename, line_number, timestamp)
screenshot_name = "screenshot-#{filename}-#{line_number}-#{timestamp}.png"
screenshot_path = "/tmp/cuprite/#{screenshot_name}"
browser.screenshot(path: screenshot_path, full: true)
rescue StandardError => e
puts "#{e.class}: #{e.message}"
end
def save_exception_log(browser, filename, line_number, timestamp)
log_name = "logfile-#{filename}-#{line_number}-#{timestamp}.txt"
File.binwrite("/tmp/cuprite/#{log_name}", browser.options.logger.string)
rescue StandardError => e
puts "#{e.class}: #{e.message}"
end
def remove_temporary_folders
FileUtils.rm_rf(File.join(PROJECT_ROOT, "spec", "tmp", "screenshots"))
FileUtils.rm_rf(Capybara.save_path)
end
end