cyperful 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/cyperful/driver.rb +6 -3
- data/lib/cyperful/framework_injections.rb +32 -34
- data/lib/cyperful/railtie.rb +9 -0
- data/lib/cyperful/test_parser.rb +20 -7
- data/lib/cyperful/ui_server.rb +46 -1
- data/lib/cyperful.rb +7 -0
- data/public/assets/index-CrBQcYdq.js +42 -0
- data/public/assets/index-Uj6YFMhM.css +1 -0
- data/public/assets/syntax-highlighter-worker-Cumko8SL.js +2798 -0
- data/public/frame-agent.js +41 -38
- data/public/index.html +4 -4
- metadata +6 -4
- data/public/assets/index-B_-TcqHl.js +0 -54
- data/public/assets/index-CDElGKtz.css +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f340215ffcef3e16c1738d36eb2b71461bbd32e2011598d000793326f806b6d4
|
4
|
+
data.tar.gz: 545e19084294a2d481a7e9d156f6ba5e4758fb52332c17dc2e2574be820b2256
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 524bbb91d707a457adfa888bc8db5a2d97886714dedc026d8647d2f243f8ff381f46a47af8cffe3fb4d46242aacfd515f2dda1b2a794252f758b5899ca312e9a
|
7
|
+
data.tar.gz: e20223308f8c0df25df5aab64d97f24d4ef6f0b57bb530106e82a3234f5701f1ca434afa87dad9b50155f73043aef6b1afbe328ebb99aed35ad53fac29dc5ef9
|
data/lib/cyperful/driver.rb
CHANGED
@@ -61,7 +61,7 @@ class Cyperful::Driver
|
|
61
61
|
@steps =
|
62
62
|
Cyperful::TestParser.new(@test_class).steps_per_test.fetch(@test_name)
|
63
63
|
|
64
|
-
|
64
|
+
editor_scheme = Cyperful.config.editor_scheme
|
65
65
|
|
66
66
|
@steps.each_with_index do |step, i|
|
67
67
|
step.merge!(
|
@@ -70,11 +70,14 @@ class Cyperful::Driver
|
|
70
70
|
start_at: nil,
|
71
71
|
end_at: nil,
|
72
72
|
paused_at: nil,
|
73
|
-
permalink:
|
73
|
+
permalink:
|
74
|
+
if editor_scheme && !editor_scheme.empty?
|
75
|
+
"#{editor_scheme}://file/#{@source_filepath}:#{step.fetch(:line)}"
|
76
|
+
end,
|
74
77
|
)
|
75
78
|
end
|
76
79
|
|
77
|
-
#
|
80
|
+
# TODO: support multiple multiple steps per line, this takes only the last instance
|
78
81
|
@step_per_line = @steps.index_by { |step| step[:line] }
|
79
82
|
|
80
83
|
@current_step = nil
|
@@ -1,5 +1,29 @@
|
|
1
1
|
require "action_dispatch/system_testing/driver"
|
2
2
|
|
3
|
+
# The Minitest test helper.
|
4
|
+
# TODO: support other test frameworks like RSpec
|
5
|
+
module Cyperful::SystemTestHelper
|
6
|
+
def setup
|
7
|
+
Cyperful.setup(self.class, self.method_name)
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
error = passed? ? nil : failure
|
13
|
+
|
14
|
+
error = error.error if error.is_a?(Minitest::UnexpectedError)
|
15
|
+
|
16
|
+
Cyperful.teardown(error)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
# Disable default screenshot on failure b/c we handle them ourselves.
|
21
|
+
# https://github.com/rails/rails/blob/main/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb#L156
|
22
|
+
def take_failed_screenshot
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
3
27
|
# we need to override the some Capybara::Session methods because they
|
4
28
|
# control the top-level browser window, but we want them
|
5
29
|
# to control the iframe instead
|
@@ -37,34 +61,14 @@ module PrependCapybaraWindow
|
|
37
61
|
end
|
38
62
|
Capybara::Window.prepend(PrependCapybaraWindow)
|
39
63
|
|
40
|
-
# The Minitest test helper.
|
41
|
-
# TODO: support other test frameworks like RSpec
|
42
|
-
module Cyperful::SystemTestHelper
|
43
|
-
def setup
|
44
|
-
Cyperful.setup(self.class, self.method_name)
|
45
|
-
super
|
46
|
-
end
|
47
|
-
|
48
|
-
def teardown
|
49
|
-
error = passed? ? nil : failure
|
50
|
-
|
51
|
-
error = error.error if error.is_a?(Minitest::UnexpectedError)
|
52
|
-
|
53
|
-
Cyperful.teardown(error)
|
54
|
-
super
|
55
|
-
end
|
56
|
-
|
57
|
-
# Disable default screenshot on failure b/c we handle them ourselves.
|
58
|
-
# https://github.com/rails/rails/blob/main/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb#L156
|
59
|
-
def take_failed_screenshot
|
60
|
-
nil
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
64
|
module PrependSystemTestingDriver
|
65
65
|
def initialize(...)
|
66
66
|
super(...)
|
67
67
|
|
68
|
+
# SUPER NAIVE way to include the width/height of the sidebar/header
|
69
|
+
# in the new screen size
|
70
|
+
@screen_size = [@screen_size.fetch(0) + 300, @screen_size.fetch(1) + 60]
|
71
|
+
|
68
72
|
prev_capabilities = @capabilities
|
69
73
|
@capabilities =
|
70
74
|
proc do |driver_opts|
|
@@ -81,6 +85,10 @@ module PrependSystemTestingDriver
|
|
81
85
|
# make sure we're not in headless mode
|
82
86
|
driver_opts.args.delete("--headless")
|
83
87
|
driver_opts.args.delete("--headless=new")
|
88
|
+
|
89
|
+
# hide the "Chrome is being controlled by automated test software" infobar
|
90
|
+
driver_opts.args.delete("--enable-automation")
|
91
|
+
driver_opts.exclude_switches << "enable-automation"
|
84
92
|
end
|
85
93
|
end
|
86
94
|
end
|
@@ -90,15 +98,5 @@ ActionDispatch::SystemTesting::Driver.prepend(PrependSystemTestingDriver)
|
|
90
98
|
# Minitest::Test::PASSTHROUGH_EXCEPTIONS << Cyperful::AbstractCommand
|
91
99
|
# end
|
92
100
|
|
93
|
-
# we need to allow the iframe to be embedded in the cyperful server
|
94
|
-
# TODO: use Rack middleware instead to support non-Rails apps
|
95
|
-
if defined?(Rails)
|
96
|
-
Rails.application.config.content_security_policy do |policy|
|
97
|
-
policy.frame_ancestors(:self, "localhost:#{Cyperful.config.port}")
|
98
|
-
end
|
99
|
-
else
|
100
|
-
warn "Cyperful: Rails not detected, skipping content_security_policy fix.\nThe Cyperful UI may not work correctly."
|
101
|
-
end
|
102
|
-
|
103
101
|
# fix for: Set-Cookie (SameSite=Lax) doesn't work when within an iframe with host 127.0.0.1
|
104
102
|
Capybara.server_host = "localhost"
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# we need to allow the iframe to be embedded in the cyperful server
|
2
|
+
# TODO: consider Rack middleware instead to support non-Rails apps?
|
3
|
+
class Cyperful::Railtie < Rails::Railtie
|
4
|
+
config.after_initialize do |app|
|
5
|
+
app.config.content_security_policy do |policy|
|
6
|
+
policy.frame_ancestors(:self, "localhost:#{Cyperful.config.port}")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
data/lib/cyperful/test_parser.rb
CHANGED
@@ -17,10 +17,12 @@ class Cyperful::TestParser
|
|
17
17
|
current_scope
|
18
18
|
status_code
|
19
19
|
response_headers
|
20
|
+
title
|
21
|
+
query
|
20
22
|
]
|
21
23
|
|
22
|
-
def self.
|
23
|
-
@step_at_methods
|
24
|
+
def self.step_at_methods_set
|
25
|
+
@step_at_methods_set ||= @step_at_methods.to_set
|
24
26
|
end
|
25
27
|
def self.add_step_at_methods(*mods_or_methods)
|
26
28
|
mods_or_methods.each do |mod_or_method|
|
@@ -78,9 +80,13 @@ class Cyperful::TestParser
|
|
78
80
|
|
79
81
|
block_node = node.children[2]
|
80
82
|
[test_method, block_node]
|
81
|
-
|
83
|
+
|
82
84
|
# e.g. `def test_my_test; ... end`
|
83
|
-
|
85
|
+
elsif node.type == :def && node.children[0].to_s.start_with?("test_")
|
86
|
+
test_method = node.children[0]
|
87
|
+
|
88
|
+
block_node = node.children[2]
|
89
|
+
[test_method, block_node]
|
84
90
|
end
|
85
91
|
end
|
86
92
|
.compact
|
@@ -88,6 +94,10 @@ class Cyperful::TestParser
|
|
88
94
|
out = []
|
89
95
|
block_node.children.each { |child| find_test_steps(child, out) }
|
90
96
|
|
97
|
+
# de-duplicate steps by line number
|
98
|
+
# TODO: support multiple steps on the same line. `step_per_line = ...` needs to be refactored
|
99
|
+
out = out.reverse.uniq { |step| step[:line] }.reverse
|
100
|
+
|
91
101
|
[test_method, out]
|
92
102
|
end
|
93
103
|
end
|
@@ -96,8 +106,10 @@ class Cyperful::TestParser
|
|
96
106
|
return out unless ast&.is_a?(Parser::AST::Node)
|
97
107
|
|
98
108
|
if ast.type == :send
|
99
|
-
|
100
|
-
|
109
|
+
# e.g. `assert_equal current_path, "/"` should be a single step, not 2
|
110
|
+
unless add_node(ast, out, depth)
|
111
|
+
ast.children.each { |child| find_test_steps(child, out, depth) }
|
112
|
+
end
|
101
113
|
elsif ast.type == :block
|
102
114
|
method, _args, child = ast.children
|
103
115
|
|
@@ -105,6 +117,7 @@ class Cyperful::TestParser
|
|
105
117
|
|
106
118
|
if method.type == :send
|
107
119
|
depth += 1 if add_node(method, out, depth)
|
120
|
+
|
108
121
|
method.children.each { |child| find_test_steps(child, out, depth) }
|
109
122
|
end
|
110
123
|
|
@@ -115,7 +128,7 @@ class Cyperful::TestParser
|
|
115
128
|
end
|
116
129
|
|
117
130
|
private def add_node(node, out, depth)
|
118
|
-
unless Cyperful::TestParser.
|
131
|
+
unless Cyperful::TestParser.step_at_methods_set.include?(node.children[1])
|
119
132
|
return false
|
120
133
|
end
|
121
134
|
|
data/lib/cyperful/ui_server.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "webrick/websocket"
|
2
|
+
require "webrick/httpproxy"
|
2
3
|
|
3
4
|
# fix for: webrick-websocket incorrectly assumes `Upgrade` header is always present
|
4
5
|
module FixWebrickWebsocketServer
|
@@ -34,9 +35,16 @@ class Cyperful::UiServer
|
|
34
35
|
@server =
|
35
36
|
WEBrick::Websocket::HTTPServer.new(
|
36
37
|
Port: @port,
|
37
|
-
DocumentRoot: File.join(Cyperful::ROOT_DIR, "public"),
|
38
38
|
Logger: WEBrick::Log.new("/dev/null"),
|
39
39
|
AccessLog: [],
|
40
|
+
**unless Cyperful::DEV_MODE
|
41
|
+
{
|
42
|
+
DocumentRoot: File.join(Cyperful::ROOT_DIR, "public"),
|
43
|
+
DocumentRootOptions: {
|
44
|
+
FancyIndexing: false,
|
45
|
+
},
|
46
|
+
}
|
47
|
+
end || {},
|
40
48
|
)
|
41
49
|
|
42
50
|
notify_queue = @notify_queue
|
@@ -118,6 +126,10 @@ class Cyperful::UiServer
|
|
118
126
|
res["Content-Type"] = "application/json"
|
119
127
|
res.status = 200
|
120
128
|
end
|
129
|
+
|
130
|
+
if Cyperful::DEV_MODE
|
131
|
+
@server.mount("/", ReverseProxy, target_url: "http://localhost:3005")
|
132
|
+
end
|
121
133
|
end
|
122
134
|
|
123
135
|
def start_async
|
@@ -134,4 +146,37 @@ class Cyperful::UiServer
|
|
134
146
|
|
135
147
|
@server.shutdown
|
136
148
|
end
|
149
|
+
|
150
|
+
# super naive reverse proxy
|
151
|
+
class ReverseProxy < WEBrick::HTTPServlet::AbstractServlet
|
152
|
+
def initialize(server, config = {})
|
153
|
+
super
|
154
|
+
@target_url = config.fetch(:target_url)
|
155
|
+
@forward_headers = config[:forward_headers] || ["accept"]
|
156
|
+
end
|
157
|
+
|
158
|
+
def do_GET(request, response)
|
159
|
+
# Target server URL
|
160
|
+
target_uri = URI(@target_url)
|
161
|
+
target_uri.path = request.path
|
162
|
+
target_uri.query = request.query_string if request.query_string
|
163
|
+
|
164
|
+
# Create a new request to the target server with the original request path
|
165
|
+
target_request = Net::HTTP::Get.new(target_uri)
|
166
|
+
@forward_headers.each do |header|
|
167
|
+
target_request[header] = request[header]
|
168
|
+
end
|
169
|
+
|
170
|
+
# Send the request to the target server
|
171
|
+
target_response =
|
172
|
+
Net::HTTP.start(target_uri.host, target_uri.port) do |http|
|
173
|
+
http.request(target_request)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Set the response from the target server as the response to send back to the client
|
177
|
+
response.status = target_response.code.to_i
|
178
|
+
response["Content-Type"] = target_response["content-type"]
|
179
|
+
response.body = target_response.body
|
180
|
+
end
|
181
|
+
end
|
137
182
|
end
|
data/lib/cyperful.rb
CHANGED
@@ -4,6 +4,10 @@ require "listen"
|
|
4
4
|
module Cyperful
|
5
5
|
ROOT_DIR = File.expand_path("..", __dir__)
|
6
6
|
|
7
|
+
# Add `CYPERFUL_DEV=1` to use the Vite dev hot-reloading server
|
8
|
+
# instead of the pre-built files in `public/`
|
9
|
+
DEV_MODE = !!ENV["CYPERFUL_DEV"]
|
10
|
+
|
7
11
|
@current = nil
|
8
12
|
|
9
13
|
class Config < Struct.new(
|
@@ -11,6 +15,7 @@ module Cyperful
|
|
11
15
|
:auto_run_on_reload,
|
12
16
|
:reload_test_files,
|
13
17
|
# :reload_source_files, # not implemented yet
|
18
|
+
:editor_scheme,
|
14
19
|
:history_recording, # EXPERIMENTAL
|
15
20
|
keyword_init: true,
|
16
21
|
)
|
@@ -19,6 +24,7 @@ module Cyperful
|
|
19
24
|
port: 3004,
|
20
25
|
auto_run_on_reload: true,
|
21
26
|
reload_test_files: true,
|
27
|
+
editor_scheme: "vscode",
|
22
28
|
history_recording: true,
|
23
29
|
)
|
24
30
|
end
|
@@ -60,3 +66,4 @@ require "cyperful/test_parser"
|
|
60
66
|
require "cyperful/ui_server"
|
61
67
|
require "cyperful/driver"
|
62
68
|
require "cyperful/framework_injections"
|
69
|
+
require "cyperful/railtie" if defined?(Rails::Railtie)
|