smartest 0.6.0.alpha1 → 0.6.1
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/CHANGELOG.md +14 -1
- data/README.md +34 -6
- data/lib/smartest/init_browser_generator.rb +18 -4
- data/lib/smartest/init_rails_generator.rb +86 -39
- data/lib/smartest/rails.rb +3 -4
- data/lib/smartest/version.rb +1 -1
- data/smartest/smartest_test.rb +248 -10
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 60329ddc39f19de585b5eca7624d830188201867f12acc4c5d455086770c6e55
|
|
4
|
+
data.tar.gz: e3b94d9094456040638436153dea247c90a09df900f73fac8a446e230cf121e6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 47ba0913bb68d3015905baa12677ed6ac2f812723935a546d0f6f9c0e0154776fb72a9e2844a77833743c97a8363066c7199c767022022b17f169415c48b9001
|
|
7
|
+
data.tar.gz: 86f5bdd1c49b6f461408c5ee21075a0a75406e8f6c139f6146871fcbd0dea6644129e63339602851f2a122ac075d6bcc7b96d95d69224e446dc5e6031c951cf9
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.6.
|
|
3
|
+
## 0.6.1
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
- Fix Rails Docker scaffold friction in `smartest --init-rails` and the
|
|
8
|
+
generated Playwright fixtures so the Docker-based browser test setup works
|
|
9
|
+
out of the box.
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
- Document fresh Rails database preparation for browser tests, including the
|
|
14
|
+
Docker-based workflow.
|
|
15
|
+
|
|
16
|
+
## 0.6.0
|
|
4
17
|
|
|
5
18
|
### New Features
|
|
6
19
|
|
data/README.md
CHANGED
|
@@ -256,15 +256,43 @@ smartest/matchers/playwright_matcher.rb
|
|
|
256
256
|
smartest/example_rails_system_test.rb
|
|
257
257
|
```
|
|
258
258
|
|
|
259
|
-
The generated fixture requires `smartest/rails
|
|
259
|
+
The generated fixture requires `smartest/rails`, loads `config/environment`
|
|
260
|
+
when `test_helper` requires the fixture file, and starts
|
|
260
261
|
`Smartest::Rails::TestServer` against `Rails.application` in the same Ruby
|
|
261
|
-
process as the test runner.
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
process as the test runner. Loading Rails during helper setup makes app
|
|
263
|
+
constants such as ActiveRecord models available inside test files and
|
|
264
|
+
`around_test` hooks before per-test fixtures are resolved. The generated
|
|
265
|
+
fixture forces `RAILS_ENV` and `RACK_ENV` to `test` before Rails boots.
|
|
266
|
+
`Smartest::Rails::TestServer` is only loaded by explicitly requiring
|
|
267
|
+
`smartest/rails`; plain `require "smartest"` does not load Puma.
|
|
268
|
+
|
|
269
|
+
This is aimed at local Rails system tests that combine Rails test data, stubs,
|
|
270
|
+
and Playwright browser assertions. It is not a Capybara compatibility layer or
|
|
271
|
+
the main choice for staging / production-like E2E suites; use Node.js
|
|
272
|
+
Playwright Test for that style of E2E testing.
|
|
264
273
|
|
|
265
274
|
The generated `page` fixture uses a per-test Playwright browser context with
|
|
266
|
-
`baseURL` set to the Rails server URL. Set
|
|
267
|
-
fixed port; otherwise the test
|
|
275
|
+
`baseURL` set to the Rails server URL. Set
|
|
276
|
+
`SMARTEST_RAILS_TEST_SERVER_PORT` when you need a fixed port; otherwise the test
|
|
277
|
+
server asks the OS for an available port.
|
|
278
|
+
|
|
279
|
+
For Docker sidecar runs, initialize without installing browser binaries into
|
|
280
|
+
the Rails app container:
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
SMARTEST_SKIP_BROWSER_DOWNLOAD=1 bundle exec smartest --init-rails
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
At runtime, set `PLAYWRIGHT_WS_ENDPOINT`,
|
|
287
|
+
`SMARTEST_RAILS_TEST_SERVER_HOST`, `SMARTEST_RAILS_TEST_SERVER_PORT`, and
|
|
288
|
+
`SMARTEST_RAILS_BASE_URL` so the generated fixture connects to the Playwright
|
|
289
|
+
sidecar and gives the browser a Docker-network URL for Rails. These are usually
|
|
290
|
+
stable Docker topology settings, so put them in `compose.yml` instead of
|
|
291
|
+
repeating them on every `docker compose run` command.
|
|
292
|
+
For a Rails Compose service named `web`, use
|
|
293
|
+
`SMARTEST_RAILS_BASE_URL=http://web:4001`; replace `web` with your service name.
|
|
294
|
+
The generated Rails fixture sets `RAILS_ENV` and `RACK_ENV` to `test`, even if
|
|
295
|
+
the same service normally runs in development.
|
|
268
296
|
|
|
269
297
|
Run the generated Rails browser example with:
|
|
270
298
|
|
|
@@ -160,11 +160,15 @@ module Smartest
|
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
def install_dependencies
|
|
163
|
-
|
|
164
|
-
@output.puts "run #{command.join(" ")}"
|
|
165
|
-
next if @command_runner.call(command, chdir: @root)
|
|
163
|
+
commands = install_commands
|
|
166
164
|
|
|
167
|
-
|
|
165
|
+
with_unbundled_env do
|
|
166
|
+
commands.each do |command|
|
|
167
|
+
@output.puts "run #{command.join(" ")}"
|
|
168
|
+
next if @command_runner.call(command, chdir: @root)
|
|
169
|
+
|
|
170
|
+
raise "command failed: #{command.join(" ")}"
|
|
171
|
+
end
|
|
168
172
|
end
|
|
169
173
|
end
|
|
170
174
|
|
|
@@ -179,5 +183,15 @@ module Smartest
|
|
|
179
183
|
def run_system_command(command, chdir:)
|
|
180
184
|
system(*command, chdir: chdir)
|
|
181
185
|
end
|
|
186
|
+
|
|
187
|
+
def with_unbundled_env(&block)
|
|
188
|
+
require "bundler"
|
|
189
|
+
|
|
190
|
+
if Bundler.respond_to?(:with_unbundled_env)
|
|
191
|
+
Bundler.with_unbundled_env(&block)
|
|
192
|
+
else
|
|
193
|
+
Bundler.with_clean_env(&block)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
182
196
|
end
|
|
183
197
|
end
|
|
@@ -10,15 +10,19 @@ module Smartest
|
|
|
10
10
|
require 'smartest/rails'
|
|
11
11
|
require "playwright"
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
ENV["RACK_ENV"] ||= ENV["RAILS_ENV"]
|
|
19
|
-
require_relative "../../config/environment"
|
|
13
|
+
# Force the test environment and load Rails while test_helper is required
|
|
14
|
+
# so app constants are available before per-test fixtures are resolved.
|
|
15
|
+
ENV["RAILS_ENV"] = "test"
|
|
16
|
+
ENV["RACK_ENV"] = "test"
|
|
17
|
+
require_relative "../../config/environment"
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
class RailsSystemTestFixture < Smartest::Fixture
|
|
20
|
+
suite_fixture :rails_server do
|
|
21
|
+
server = Smartest::Rails::TestServer.new(
|
|
22
|
+
app: Rails.application,
|
|
23
|
+
host: ENV["SMARTEST_RAILS_TEST_SERVER_HOST"],
|
|
24
|
+
port: ENV["SMARTEST_RAILS_TEST_SERVER_PORT"],
|
|
25
|
+
)
|
|
22
26
|
server.start
|
|
23
27
|
server.wait_for_ready
|
|
24
28
|
|
|
@@ -31,36 +35,34 @@ module Smartest
|
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
suite_fixture :base_url do |rails_server:|
|
|
34
|
-
rails_server.base_url
|
|
38
|
+
ENV.fetch("SMARTEST_RAILS_BASE_URL", rails_server.base_url)
|
|
35
39
|
end
|
|
36
40
|
|
|
37
|
-
suite_fixture :
|
|
38
|
-
|
|
39
|
-
playwright_cli_executable_path: "./node_modules/.bin/playwright",
|
|
40
|
-
)
|
|
41
|
-
on_teardown { runtime.stop }
|
|
42
|
-
runtime.playwright
|
|
43
|
-
end
|
|
41
|
+
suite_fixture :browser do
|
|
42
|
+
ws_endpoint = ENV["PLAYWRIGHT_WS_ENDPOINT"]
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
else
|
|
52
|
-
:chromium
|
|
53
|
-
end
|
|
44
|
+
if ws_endpoint && !ws_endpoint.empty?
|
|
45
|
+
playwright_execution = Playwright.connect_to_browser_server(
|
|
46
|
+
ws_endpoint,
|
|
47
|
+
browser_type: selected_browser_type.to_s,
|
|
48
|
+
)
|
|
49
|
+
on_teardown { playwright_execution.stop }
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
playwright_execution.browser
|
|
52
|
+
else
|
|
53
|
+
playwright_execution = Playwright.create(
|
|
54
|
+
playwright_cli_executable_path: ENV.fetch(
|
|
55
|
+
"PLAYWRIGHT_CLI_EXECUTABLE_PATH",
|
|
56
|
+
"./node_modules/.bin/playwright",
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
on_teardown { playwright_execution.stop }
|
|
60
|
+
|
|
61
|
+
playwright = playwright_execution.playwright
|
|
62
|
+
browser = playwright.public_send(selected_browser_type).launch(**browser_launch_options)
|
|
63
|
+
on_teardown { browser.close }
|
|
64
|
+
browser
|
|
59
65
|
end
|
|
60
|
-
|
|
61
|
-
browser = playwright.send(browser_type).launch(**launch_options)
|
|
62
|
-
on_teardown { browser.close }
|
|
63
|
-
browser
|
|
64
66
|
end
|
|
65
67
|
|
|
66
68
|
fixture :browser_context do |base_url:, browser:|
|
|
@@ -74,6 +76,29 @@ module Smartest
|
|
|
74
76
|
on_teardown { page.close }
|
|
75
77
|
page
|
|
76
78
|
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
def selected_browser_type
|
|
83
|
+
case ENV.fetch("BROWSER", "chromium")
|
|
84
|
+
when "firefox"
|
|
85
|
+
:firefox
|
|
86
|
+
when "webkit"
|
|
87
|
+
:webkit
|
|
88
|
+
else
|
|
89
|
+
:chromium
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def browser_launch_options
|
|
94
|
+
launch_options = {}
|
|
95
|
+
launch_options[:headless] = !%w[0 false].include?(ENV.fetch("HEADLESS", "true"))
|
|
96
|
+
if (slow_mo = ENV.fetch("SLOW_MO", "0").to_i) > 0
|
|
97
|
+
launch_options[:slowMo] = slow_mo
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
launch_options
|
|
101
|
+
end
|
|
77
102
|
end
|
|
78
103
|
RUBY
|
|
79
104
|
|
|
@@ -156,7 +181,7 @@ module Smartest
|
|
|
156
181
|
|
|
157
182
|
def ensure_rails_registered(contents)
|
|
158
183
|
missing_lines = []
|
|
159
|
-
missing_lines << " use_fixture
|
|
184
|
+
missing_lines << " use_fixture RailsSystemTestFixture\n" unless contents.include?("use_fixture RailsSystemTestFixture")
|
|
160
185
|
missing_lines << " use_matcher PlaywrightMatcher\n" unless contents.include?("use_matcher PlaywrightMatcher")
|
|
161
186
|
return contents if missing_lines.empty?
|
|
162
187
|
|
|
@@ -186,11 +211,19 @@ module Smartest
|
|
|
186
211
|
end
|
|
187
212
|
|
|
188
213
|
def install_dependencies
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
214
|
+
commands = install_commands
|
|
215
|
+
|
|
216
|
+
with_unbundled_env do
|
|
217
|
+
commands.each do |command|
|
|
218
|
+
@output.puts "run #{command.join(" ")}"
|
|
219
|
+
next if @command_runner.call(command, chdir: @root)
|
|
192
220
|
|
|
193
|
-
|
|
221
|
+
raise "command failed: #{command.join(" ")}"
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
if skip_browser_download?
|
|
226
|
+
@output.puts "skip ./node_modules/.bin/playwright install (SMARTEST_SKIP_BROWSER_DOWNLOAD=1)"
|
|
194
227
|
end
|
|
195
228
|
end
|
|
196
229
|
|
|
@@ -198,12 +231,26 @@ module Smartest
|
|
|
198
231
|
commands = [["bundle", "install"]]
|
|
199
232
|
commands << ["npm", "init", "--yes"] unless File.exist?(File.join(@root, "package.json"))
|
|
200
233
|
commands << ["npm", "install", "playwright", "--save-dev"]
|
|
201
|
-
commands << ["./node_modules/.bin/playwright", "install"]
|
|
234
|
+
commands << ["./node_modules/.bin/playwright", "install"] unless skip_browser_download?
|
|
202
235
|
commands
|
|
203
236
|
end
|
|
204
237
|
|
|
238
|
+
def skip_browser_download?
|
|
239
|
+
%w[1 true].include?(ENV.fetch("SMARTEST_SKIP_BROWSER_DOWNLOAD", "false"))
|
|
240
|
+
end
|
|
241
|
+
|
|
205
242
|
def run_system_command(command, chdir:)
|
|
206
243
|
system(*command, chdir: chdir)
|
|
207
244
|
end
|
|
245
|
+
|
|
246
|
+
def with_unbundled_env(&block)
|
|
247
|
+
require "bundler"
|
|
248
|
+
|
|
249
|
+
if Bundler.respond_to?(:with_unbundled_env)
|
|
250
|
+
Bundler.with_unbundled_env(&block)
|
|
251
|
+
else
|
|
252
|
+
Bundler.with_clean_env(&block)
|
|
253
|
+
end
|
|
254
|
+
end
|
|
208
255
|
end
|
|
209
256
|
end
|
data/lib/smartest/rails.rb
CHANGED
|
@@ -9,15 +9,14 @@ require_relative "../smartest"
|
|
|
9
9
|
module Smartest
|
|
10
10
|
module Rails
|
|
11
11
|
class TestServer
|
|
12
|
-
DEFAULT_HOST = "127.0.0.1"
|
|
13
12
|
DEFAULT_READY_TIMEOUT = 10
|
|
14
13
|
|
|
15
14
|
attr_reader :host, :port
|
|
16
15
|
|
|
17
|
-
def initialize(app:, host:
|
|
16
|
+
def initialize(app:, host: nil, port: nil)
|
|
18
17
|
@app = app
|
|
19
|
-
@host = host
|
|
20
|
-
@requested_port = port
|
|
18
|
+
@host = host || "127.0.0.1"
|
|
19
|
+
@requested_port = port ? port.to_i : 0
|
|
21
20
|
@server = Puma::Server.new(@app)
|
|
22
21
|
@port = bind_tcp_listener
|
|
23
22
|
@thread = nil
|
data/lib/smartest/version.rb
CHANGED
data/smartest/smartest_test.rb
CHANGED
|
@@ -9,6 +9,8 @@ require "open3"
|
|
|
9
9
|
require "tmpdir"
|
|
10
10
|
|
|
11
11
|
module SmartestSelfTest
|
|
12
|
+
ENV_MISSING = Object.new.freeze
|
|
13
|
+
|
|
12
14
|
module_function
|
|
13
15
|
|
|
14
16
|
def test_case(name, block)
|
|
@@ -40,6 +42,20 @@ module SmartestSelfTest
|
|
|
40
42
|
else
|
|
41
43
|
raise Smartest::AssertionFailed, "expected #{expected_error}, but nothing was raised"
|
|
42
44
|
end
|
|
45
|
+
|
|
46
|
+
def with_env(values)
|
|
47
|
+
previous_values = {}
|
|
48
|
+
values.each do |key, value|
|
|
49
|
+
previous_values[key] = ENV.fetch(key, ENV_MISSING)
|
|
50
|
+
value.nil? ? ENV.delete(key) : ENV[key] = value
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
yield
|
|
54
|
+
ensure
|
|
55
|
+
previous_values.each do |key, value|
|
|
56
|
+
value.equal?(ENV_MISSING) ? ENV.delete(key) : ENV[key] = value
|
|
57
|
+
end
|
|
58
|
+
end
|
|
43
59
|
end
|
|
44
60
|
|
|
45
61
|
class SelfTestRegisteredFixture < Smartest::Fixture
|
|
@@ -2167,6 +2183,49 @@ test("cli browser init generator creates Playwright scaffold and installation co
|
|
|
2167
2183
|
end
|
|
2168
2184
|
end
|
|
2169
2185
|
|
|
2186
|
+
test("cli browser init generator runs installation commands outside the current Bundler environment") do
|
|
2187
|
+
require "bundler"
|
|
2188
|
+
|
|
2189
|
+
Dir.mktmpdir do |dir|
|
|
2190
|
+
File.write(File.join(dir, "Gemfile"), <<~RUBY)
|
|
2191
|
+
source "https://rubygems.org"
|
|
2192
|
+
|
|
2193
|
+
gem "smartest"
|
|
2194
|
+
RUBY
|
|
2195
|
+
|
|
2196
|
+
command_environments = []
|
|
2197
|
+
output = StringIO.new
|
|
2198
|
+
generator = Smartest::InitBrowserGenerator.new(
|
|
2199
|
+
root: dir,
|
|
2200
|
+
output: output,
|
|
2201
|
+
command_runner: ->(_command, chdir:) {
|
|
2202
|
+
command_environments << {
|
|
2203
|
+
bundle_gemfile: ENV["BUNDLE_GEMFILE"],
|
|
2204
|
+
bundle_bin_path: ENV["BUNDLE_BIN_PATH"],
|
|
2205
|
+
rubyopt: ENV["RUBYOPT"]
|
|
2206
|
+
}
|
|
2207
|
+
true
|
|
2208
|
+
}
|
|
2209
|
+
)
|
|
2210
|
+
|
|
2211
|
+
SmartestSelfTest.with_env(
|
|
2212
|
+
"BUNDLE_GEMFILE" => File.join(dir, "Gemfile"),
|
|
2213
|
+
"BUNDLE_BIN_PATH" => "/tmp/smartest-self-test-bundle",
|
|
2214
|
+
"RUBYOPT" => "-rbundler/setup -W0"
|
|
2215
|
+
) do
|
|
2216
|
+
status = generator.run
|
|
2217
|
+
expect(status).to eq(0)
|
|
2218
|
+
end
|
|
2219
|
+
|
|
2220
|
+
expect(command_environments.length).to eq(4)
|
|
2221
|
+
expect(command_environments.all? do |environment|
|
|
2222
|
+
environment[:bundle_gemfile].nil? &&
|
|
2223
|
+
environment[:bundle_bin_path].nil? &&
|
|
2224
|
+
!environment[:rubyopt].to_s.include?("bundler/setup")
|
|
2225
|
+
end).to eq(true)
|
|
2226
|
+
end
|
|
2227
|
+
end
|
|
2228
|
+
|
|
2170
2229
|
test("cli browser init generator skips npm init when package.json already exists") do
|
|
2171
2230
|
Dir.mktmpdir do |dir|
|
|
2172
2231
|
File.write(File.join(dir, "Gemfile"), <<~RUBY)
|
|
@@ -2230,7 +2289,7 @@ test("smartest rails helper is loaded only by explicit require") do
|
|
|
2230
2289
|
end
|
|
2231
2290
|
end
|
|
2232
2291
|
|
|
2233
|
-
test("smartest rails test server wraps puma with
|
|
2292
|
+
test("smartest rails test server wraps puma with explicit arguments and lifecycle") do
|
|
2234
2293
|
lib_path = File.expand_path("../lib", __dir__)
|
|
2235
2294
|
|
|
2236
2295
|
Dir.mktmpdir do |dir|
|
|
@@ -2269,25 +2328,32 @@ test("smartest rails test server wraps puma with env port and lifecycle") do
|
|
|
2269
2328
|
RUBY
|
|
2270
2329
|
|
|
2271
2330
|
stdout, stderr, status = Open3.capture3(
|
|
2272
|
-
{
|
|
2331
|
+
{
|
|
2332
|
+
"RUBYLIB" => "#{dir}:#{lib_path}",
|
|
2333
|
+
"SMARTEST_RAILS_TEST_SERVER_HOST" => "0.0.0.0",
|
|
2334
|
+
"SMARTEST_RAILS_TEST_SERVER_PORT" => "9876",
|
|
2335
|
+
"SMARTEST_RAILS_BASE_URL" => "http://app:9876"
|
|
2336
|
+
},
|
|
2273
2337
|
"ruby",
|
|
2274
2338
|
"-e",
|
|
2275
2339
|
<<~'RUBY'
|
|
2276
2340
|
require "smartest/rails"
|
|
2277
2341
|
|
|
2278
|
-
server = Smartest::Rails::TestServer.new(app: Object.new)
|
|
2342
|
+
server = Smartest::Rails::TestServer.new(app: Object.new, port: "4567")
|
|
2343
|
+
default_port_server = Smartest::Rails::TestServer.new(app: Object.new)
|
|
2279
2344
|
thread = server.start
|
|
2280
2345
|
server.stop
|
|
2281
2346
|
server.wait_for_stopped
|
|
2282
2347
|
|
|
2283
2348
|
puts server.base_url
|
|
2349
|
+
puts default_port_server.base_url
|
|
2284
2350
|
puts thread.is_a?(Thread)
|
|
2285
2351
|
RUBY
|
|
2286
2352
|
)
|
|
2287
2353
|
|
|
2288
2354
|
expect(status.success?).to eq(true)
|
|
2289
2355
|
expect(stderr).to eq("")
|
|
2290
|
-
expect(stdout).to eq("http://127.0.0.1:4567\ntrue\n")
|
|
2356
|
+
expect(stdout).to eq("http://127.0.0.1:4567\nhttp://127.0.0.1:4321\ntrue\n")
|
|
2291
2357
|
end
|
|
2292
2358
|
end
|
|
2293
2359
|
|
|
@@ -2316,14 +2382,42 @@ test("cli rails init generator creates Rails browser scaffold and installation c
|
|
|
2316
2382
|
expect(status).to eq(0)
|
|
2317
2383
|
rails_fixture = File.read(File.join(dir, "smartest/fixtures/rails_system_fixture.rb"))
|
|
2318
2384
|
expect(rails_fixture).to include("require 'smartest/rails'")
|
|
2319
|
-
expect(rails_fixture).to include("class
|
|
2385
|
+
expect(rails_fixture).to include("class RailsSystemTestFixture < Smartest::Fixture")
|
|
2320
2386
|
expect(rails_fixture).to include("suite_fixture :rails_server")
|
|
2321
|
-
expect(rails_fixture).to include("
|
|
2387
|
+
expect(rails_fixture).to include('ENV["RAILS_ENV"] = "test"')
|
|
2388
|
+
expect(rails_fixture).to include('ENV["RACK_ENV"] = "test"')
|
|
2389
|
+
expect(rails_fixture).not_to include('ENV["RAILS_ENV"] ||=')
|
|
2390
|
+
expect(rails_fixture).to include("constants are available before per-test fixtures are resolved")
|
|
2322
2391
|
expect(rails_fixture).to include('require_relative "../../config/environment"')
|
|
2323
|
-
expect(rails_fixture
|
|
2392
|
+
expect(rails_fixture.index('require_relative "../../config/environment"') < rails_fixture.index("class RailsSystemTestFixture")).to eq(true)
|
|
2393
|
+
expect(rails_fixture).to include("Smartest::Rails::TestServer.new(")
|
|
2394
|
+
expect(rails_fixture).to include('host: ENV["SMARTEST_RAILS_TEST_SERVER_HOST"]')
|
|
2395
|
+
expect(rails_fixture).not_to include("bind_host:")
|
|
2396
|
+
expect(rails_fixture).to include('port: ENV["SMARTEST_RAILS_TEST_SERVER_PORT"]')
|
|
2397
|
+
expect(rails_fixture).not_to include("public_base_url")
|
|
2324
2398
|
expect(rails_fixture).not_to include("SmartestRailsTestServer")
|
|
2325
2399
|
expect(rails_fixture).not_to include("Puma::Server")
|
|
2326
2400
|
expect(rails_fixture).to include("suite_fixture :base_url")
|
|
2401
|
+
expect(rails_fixture).to include('ENV.fetch("SMARTEST_RAILS_BASE_URL", rails_server.base_url)')
|
|
2402
|
+
expect(rails_fixture).not_to include("rails_test_server_port")
|
|
2403
|
+
expect(rails_fixture).not_to include("SMARTEST_RAILS_PORT")
|
|
2404
|
+
expect(rails_fixture).to include('ws_endpoint = ENV["PLAYWRIGHT_WS_ENDPOINT"]')
|
|
2405
|
+
expect(rails_fixture).not_to include("suite_fixture :playwright_execution")
|
|
2406
|
+
expect(rails_fixture).not_to include("suite_fixture :playwright do")
|
|
2407
|
+
expect(rails_fixture).not_to include("Playwright.connect_to_playwright_server")
|
|
2408
|
+
expect(rails_fixture).not_to include("rescue NotImplementedError")
|
|
2409
|
+
expect(rails_fixture).to include("playwright_execution = Playwright.connect_to_browser_server(")
|
|
2410
|
+
expect(rails_fixture).to include("browser_type: selected_browser_type.to_s")
|
|
2411
|
+
expect(rails_fixture).to include("playwright_execution.browser")
|
|
2412
|
+
expect(rails_fixture).to include('ENV.fetch(')
|
|
2413
|
+
expect(rails_fixture).to include('"PLAYWRIGHT_CLI_EXECUTABLE_PATH"')
|
|
2414
|
+
expect(rails_fixture).to include("suite_fixture :browser do")
|
|
2415
|
+
expect(rails_fixture).to include("playwright_execution = Playwright.create(")
|
|
2416
|
+
expect(rails_fixture).to include("on_teardown { playwright_execution.stop }")
|
|
2417
|
+
expect(rails_fixture).to include("playwright = playwright_execution.playwright")
|
|
2418
|
+
expect(rails_fixture).to include("playwright.public_send(selected_browser_type).launch(**browser_launch_options)")
|
|
2419
|
+
expect(rails_fixture).to include("def selected_browser_type")
|
|
2420
|
+
expect(rails_fixture).to include("def browser_launch_options")
|
|
2327
2421
|
expect(rails_fixture).to include("fixture :browser_context do |base_url:, browser:|")
|
|
2328
2422
|
expect(rails_fixture).to include("context = browser.new_context(baseURL: base_url)")
|
|
2329
2423
|
expect(rails_fixture).to include("fixture :page do |browser_context:|")
|
|
@@ -2334,7 +2428,7 @@ test("cli rails init generator creates Rails browser scaffold and installation c
|
|
|
2334
2428
|
expect(example_test).to include("expect(response.status).to be_between(200, 599)")
|
|
2335
2429
|
|
|
2336
2430
|
helper_contents = File.read(File.join(dir, "smartest/test_helper.rb"))
|
|
2337
|
-
expect(helper_contents).to include("use_matcher PredicateMatcher\n use_fixture
|
|
2431
|
+
expect(helper_contents).to include("use_matcher PredicateMatcher\n use_fixture RailsSystemTestFixture\n use_matcher PlaywrightMatcher\n suite.run")
|
|
2338
2432
|
expect(helper_contents).not_to include("Smartest::SimpleStub")
|
|
2339
2433
|
|
|
2340
2434
|
gemfile_contents = File.read(File.join(dir, "Gemfile"))
|
|
@@ -2351,6 +2445,150 @@ test("cli rails init generator creates Rails browser scaffold and installation c
|
|
|
2351
2445
|
end
|
|
2352
2446
|
end
|
|
2353
2447
|
|
|
2448
|
+
test("cli rails init generator forces Rails test environment when the generated fixture is required") do
|
|
2449
|
+
Dir.mktmpdir do |dir|
|
|
2450
|
+
FileUtils.mkdir_p(File.join(dir, "config"))
|
|
2451
|
+
File.write(File.join(dir, "Gemfile"), <<~RUBY)
|
|
2452
|
+
source "https://rubygems.org"
|
|
2453
|
+
|
|
2454
|
+
gem "rails"
|
|
2455
|
+
gem "smartest"
|
|
2456
|
+
RUBY
|
|
2457
|
+
File.write(File.join(dir, "config/environment.rb"), <<~RUBY)
|
|
2458
|
+
raise "RAILS_ENV was not set before loading Rails" unless ENV["RAILS_ENV"] == "test"
|
|
2459
|
+
raise "RACK_ENV was not set before loading Rails" unless ENV["RACK_ENV"] == "test"
|
|
2460
|
+
|
|
2461
|
+
class User
|
|
2462
|
+
end
|
|
2463
|
+
RUBY
|
|
2464
|
+
|
|
2465
|
+
stub_dir = File.join(dir, "stub_load_path")
|
|
2466
|
+
FileUtils.mkdir_p(File.join(stub_dir, "smartest"))
|
|
2467
|
+
File.write(File.join(stub_dir, "smartest/rails.rb"), <<~RUBY)
|
|
2468
|
+
module Smartest
|
|
2469
|
+
class Fixture
|
|
2470
|
+
def self.suite_fixture(*)
|
|
2471
|
+
end
|
|
2472
|
+
|
|
2473
|
+
def self.fixture(*)
|
|
2474
|
+
end
|
|
2475
|
+
end
|
|
2476
|
+
|
|
2477
|
+
module Rails
|
|
2478
|
+
end
|
|
2479
|
+
end
|
|
2480
|
+
RUBY
|
|
2481
|
+
File.write(File.join(stub_dir, "playwright.rb"), "")
|
|
2482
|
+
|
|
2483
|
+
generator = Smartest::InitRailsGenerator.new(
|
|
2484
|
+
root: dir,
|
|
2485
|
+
output: StringIO.new,
|
|
2486
|
+
command_runner: ->(_command, chdir:) { true }
|
|
2487
|
+
)
|
|
2488
|
+
generator.run
|
|
2489
|
+
|
|
2490
|
+
stdout, stderr, status = Open3.capture3(
|
|
2491
|
+
{
|
|
2492
|
+
"RUBYLIB" => stub_dir,
|
|
2493
|
+
"RAILS_ENV" => "development",
|
|
2494
|
+
"RACK_ENV" => "development"
|
|
2495
|
+
},
|
|
2496
|
+
"ruby",
|
|
2497
|
+
"-e",
|
|
2498
|
+
<<~RUBY
|
|
2499
|
+
require #{File.join(dir, "smartest/fixtures/rails_system_fixture").inspect}
|
|
2500
|
+
puts User.name
|
|
2501
|
+
RUBY
|
|
2502
|
+
)
|
|
2503
|
+
|
|
2504
|
+
expect(status.success?).to eq(true)
|
|
2505
|
+
expect(stderr).to eq("")
|
|
2506
|
+
expect(stdout).to eq("User\n")
|
|
2507
|
+
end
|
|
2508
|
+
end
|
|
2509
|
+
|
|
2510
|
+
test("cli rails init generator runs installation commands outside the current Bundler environment") do
|
|
2511
|
+
require "bundler"
|
|
2512
|
+
|
|
2513
|
+
Dir.mktmpdir do |dir|
|
|
2514
|
+
File.write(File.join(dir, "Gemfile"), <<~RUBY)
|
|
2515
|
+
source "https://rubygems.org"
|
|
2516
|
+
|
|
2517
|
+
gem "rails"
|
|
2518
|
+
gem "smartest"
|
|
2519
|
+
RUBY
|
|
2520
|
+
|
|
2521
|
+
command_environments = []
|
|
2522
|
+
output = StringIO.new
|
|
2523
|
+
generator = Smartest::InitRailsGenerator.new(
|
|
2524
|
+
root: dir,
|
|
2525
|
+
output: output,
|
|
2526
|
+
command_runner: ->(_command, chdir:) {
|
|
2527
|
+
command_environments << {
|
|
2528
|
+
bundle_gemfile: ENV["BUNDLE_GEMFILE"],
|
|
2529
|
+
bundle_bin_path: ENV["BUNDLE_BIN_PATH"],
|
|
2530
|
+
rubyopt: ENV["RUBYOPT"]
|
|
2531
|
+
}
|
|
2532
|
+
true
|
|
2533
|
+
}
|
|
2534
|
+
)
|
|
2535
|
+
|
|
2536
|
+
SmartestSelfTest.with_env(
|
|
2537
|
+
"BUNDLE_GEMFILE" => File.join(dir, "Gemfile"),
|
|
2538
|
+
"BUNDLE_BIN_PATH" => "/tmp/smartest-self-test-bundle",
|
|
2539
|
+
"RUBYOPT" => "-rbundler/setup -W0"
|
|
2540
|
+
) do
|
|
2541
|
+
status = generator.run
|
|
2542
|
+
expect(status).to eq(0)
|
|
2543
|
+
end
|
|
2544
|
+
|
|
2545
|
+
expect(command_environments.length).to eq(4)
|
|
2546
|
+
expect(command_environments.all? do |environment|
|
|
2547
|
+
environment[:bundle_gemfile].nil? &&
|
|
2548
|
+
environment[:bundle_bin_path].nil? &&
|
|
2549
|
+
!environment[:rubyopt].to_s.include?("bundler/setup")
|
|
2550
|
+
end).to eq(true)
|
|
2551
|
+
end
|
|
2552
|
+
end
|
|
2553
|
+
|
|
2554
|
+
test("cli rails init generator skips browser install when requested by environment") do
|
|
2555
|
+
SmartestSelfTest.with_env("SMARTEST_SKIP_BROWSER_DOWNLOAD" => "1") do
|
|
2556
|
+
Dir.mktmpdir do |dir|
|
|
2557
|
+
File.write(File.join(dir, "Gemfile"), <<~RUBY)
|
|
2558
|
+
source "https://rubygems.org"
|
|
2559
|
+
|
|
2560
|
+
gem "rails"
|
|
2561
|
+
gem "smartest"
|
|
2562
|
+
RUBY
|
|
2563
|
+
|
|
2564
|
+
commands = []
|
|
2565
|
+
output = StringIO.new
|
|
2566
|
+
generator = Smartest::InitRailsGenerator.new(
|
|
2567
|
+
root: dir,
|
|
2568
|
+
output: output,
|
|
2569
|
+
command_runner: ->(command, chdir:) {
|
|
2570
|
+
commands << [command, chdir]
|
|
2571
|
+
true
|
|
2572
|
+
}
|
|
2573
|
+
)
|
|
2574
|
+
|
|
2575
|
+
status = generator.run
|
|
2576
|
+
|
|
2577
|
+
expect(status).to eq(0)
|
|
2578
|
+
expect(commands).to eq(
|
|
2579
|
+
[
|
|
2580
|
+
[["bundle", "install"], dir],
|
|
2581
|
+
[["npm", "init", "--yes"], dir],
|
|
2582
|
+
[["npm", "install", "playwright", "--save-dev"], dir]
|
|
2583
|
+
]
|
|
2584
|
+
)
|
|
2585
|
+
expect(output.string).to include("skip ./node_modules/.bin/playwright install (SMARTEST_SKIP_BROWSER_DOWNLOAD=1)")
|
|
2586
|
+
expect(File.exist?(File.join(dir, "smartest/fixtures/rails_system_fixture.rb"))).to eq(true)
|
|
2587
|
+
expect(File.exist?(File.join(dir, "smartest/example_rails_system_test.rb"))).to eq(true)
|
|
2588
|
+
end
|
|
2589
|
+
end
|
|
2590
|
+
end
|
|
2591
|
+
|
|
2354
2592
|
test("cli rails init generator skips duplicate registration and dependencies") do
|
|
2355
2593
|
Dir.mktmpdir do |dir|
|
|
2356
2594
|
FileUtils.mkdir_p(File.join(dir, "smartest/fixtures"))
|
|
@@ -2367,7 +2605,7 @@ test("cli rails init generator skips duplicate registration and dependencies") d
|
|
|
2367
2605
|
|
|
2368
2606
|
around_suite do |suite|
|
|
2369
2607
|
use_matcher PredicateMatcher
|
|
2370
|
-
use_fixture
|
|
2608
|
+
use_fixture RailsSystemTestFixture
|
|
2371
2609
|
use_matcher PlaywrightMatcher
|
|
2372
2610
|
suite.run
|
|
2373
2611
|
end
|
|
@@ -2388,7 +2626,7 @@ test("cli rails init generator skips duplicate registration and dependencies") d
|
|
|
2388
2626
|
|
|
2389
2627
|
expect(status).to eq(0)
|
|
2390
2628
|
helper_contents = File.read(File.join(dir, "smartest/test_helper.rb"))
|
|
2391
|
-
expect(helper_contents.scan("use_fixture
|
|
2629
|
+
expect(helper_contents.scan("use_fixture RailsSystemTestFixture").length).to eq(1)
|
|
2392
2630
|
expect(helper_contents.scan("use_matcher PlaywrightMatcher").length).to eq(1)
|
|
2393
2631
|
expect(helper_contents).not_to include("Smartest::SimpleStub")
|
|
2394
2632
|
expect(commands).to eq(
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: smartest
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yusuke Iwaki
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|
|
@@ -103,9 +103,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
103
103
|
version: '2.7'
|
|
104
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
105
|
requirements:
|
|
106
|
-
- - "
|
|
106
|
+
- - ">="
|
|
107
107
|
- !ruby/object:Gem::Version
|
|
108
|
-
version:
|
|
108
|
+
version: '0'
|
|
109
109
|
requirements: []
|
|
110
110
|
rubygems_version: 3.4.19
|
|
111
111
|
signing_key:
|