smartest 0.6.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c8e44520f35d8daac5d01122fd2dc2b1f70f0fcbc61c1ff1d2a6c8ce5179a72
4
- data.tar.gz: 4400e77b387079fa88978ff82d34b492f250fdf6de75aae773911a5b91672169
3
+ metadata.gz: 60329ddc39f19de585b5eca7624d830188201867f12acc4c5d455086770c6e55
4
+ data.tar.gz: e3b94d9094456040638436153dea247c90a09df900f73fac8a446e230cf121e6
5
5
  SHA512:
6
- metadata.gz: b5f7dde5de541b2eec20747164936cee3945076fb985c636d4ae2ea2473e0e2b795b9e5b393800b198e2bae5ae8c6e0892ab173d74e995404a1f4941ce27fd57
7
- data.tar.gz: 0226224e48d5dfcaa82b9b22fc03ab295cab9fd463f5f0e17bab881d38e9f68eb98946641a45f5b6a13a884d1649c714a6e8aacd86e772b1aa6ec9d82fbf323c
6
+ metadata.gz: 47ba0913bb68d3015905baa12677ed6ac2f812723935a546d0f6f9c0e0154776fb72a9e2844a77833743c97a8363066c7199c767022022b17f169415c48b9001
7
+ data.tar.gz: 86f5bdd1c49b6f461408c5ee21075a0a75406e8f6c139f6146871fcbd0dea6644129e63339602851f2a122ac075d6bcc7b96d95d69224e446dc5e6031c951cf9
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
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
+
3
16
  ## 0.6.0
4
17
 
5
18
  ### New Features
data/README.md CHANGED
@@ -256,11 +256,15 @@ smartest/matchers/playwright_matcher.rb
256
256
  smartest/example_rails_system_test.rb
257
257
  ```
258
258
 
259
- The generated fixture requires `smartest/rails` and starts
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. `Smartest::Rails::TestServer` is only loaded by
262
- explicitly requiring `smartest/rails`; plain `require "smartest"` does not load
263
- Puma.
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.
264
268
 
265
269
  This is aimed at local Rails system tests that combine Rails test data, stubs,
266
270
  and Playwright browser assertions. It is not a Capybara compatibility layer or
@@ -282,7 +286,13 @@ SMARTEST_SKIP_BROWSER_DOWNLOAD=1 bundle exec smartest --init-rails
282
286
  At runtime, set `PLAYWRIGHT_WS_ENDPOINT`,
283
287
  `SMARTEST_RAILS_TEST_SERVER_HOST`, `SMARTEST_RAILS_TEST_SERVER_PORT`, and
284
288
  `SMARTEST_RAILS_BASE_URL` so the generated fixture connects to the Playwright
285
- sidecar and gives the browser a Docker-network URL for Rails.
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.
286
296
 
287
297
  Run the generated Rails browser example with:
288
298
 
@@ -160,11 +160,15 @@ module Smartest
160
160
  end
161
161
 
162
162
  def install_dependencies
163
- install_commands.each do |command|
164
- @output.puts "run #{command.join(" ")}"
165
- next if @command_runner.call(command, chdir: @root)
163
+ commands = install_commands
166
164
 
167
- raise "command failed: #{command.join(" ")}"
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,14 +10,14 @@ module Smartest
10
10
  require 'smartest/rails'
11
11
  require "playwright"
12
12
 
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"
18
+
13
19
  class RailsSystemTestFixture < Smartest::Fixture
14
20
  suite_fixture :rails_server do
15
- # Set the environment before loading config/environment so the test
16
- # server cannot boot against the development database by default.
17
- ENV["RAILS_ENV"] ||= "test"
18
- ENV["RACK_ENV"] ||= ENV["RAILS_ENV"]
19
- require_relative "../../config/environment"
20
-
21
21
  server = Smartest::Rails::TestServer.new(
22
22
  app: Rails.application,
23
23
  host: ENV["SMARTEST_RAILS_TEST_SERVER_HOST"],
@@ -211,11 +211,15 @@ module Smartest
211
211
  end
212
212
 
213
213
  def install_dependencies
214
- install_commands.each do |command|
215
- @output.puts "run #{command.join(" ")}"
216
- next if @command_runner.call(command, chdir: @root)
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)
217
220
 
218
- raise "command failed: #{command.join(" ")}"
221
+ raise "command failed: #{command.join(" ")}"
222
+ end
219
223
  end
220
224
 
221
225
  if skip_browser_download?
@@ -238,5 +242,15 @@ module Smartest
238
242
  def run_system_command(command, chdir:)
239
243
  system(*command, chdir: chdir)
240
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
241
255
  end
242
256
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Smartest
4
- VERSION = "0.6.0"
4
+ VERSION = "0.6.1"
5
5
  end
@@ -2183,6 +2183,49 @@ test("cli browser init generator creates Playwright scaffold and installation co
2183
2183
  end
2184
2184
  end
2185
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
+
2186
2229
  test("cli browser init generator skips npm init when package.json already exists") do
2187
2230
  Dir.mktmpdir do |dir|
2188
2231
  File.write(File.join(dir, "Gemfile"), <<~RUBY)
@@ -2341,8 +2384,12 @@ test("cli rails init generator creates Rails browser scaffold and installation c
2341
2384
  expect(rails_fixture).to include("require 'smartest/rails'")
2342
2385
  expect(rails_fixture).to include("class RailsSystemTestFixture < Smartest::Fixture")
2343
2386
  expect(rails_fixture).to include("suite_fixture :rails_server")
2344
- expect(rails_fixture).to include("server cannot boot against the development database")
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")
2345
2391
  expect(rails_fixture).to include('require_relative "../../config/environment"')
2392
+ expect(rails_fixture.index('require_relative "../../config/environment"') < rails_fixture.index("class RailsSystemTestFixture")).to eq(true)
2346
2393
  expect(rails_fixture).to include("Smartest::Rails::TestServer.new(")
2347
2394
  expect(rails_fixture).to include('host: ENV["SMARTEST_RAILS_TEST_SERVER_HOST"]')
2348
2395
  expect(rails_fixture).not_to include("bind_host:")
@@ -2398,6 +2445,112 @@ test("cli rails init generator creates Rails browser scaffold and installation c
2398
2445
  end
2399
2446
  end
2400
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
+
2401
2554
  test("cli rails init generator skips browser install when requested by environment") do
2402
2555
  SmartestSelfTest.with_env("SMARTEST_SKIP_BROWSER_DOWNLOAD" => "1") do
2403
2556
  Dir.mktmpdir do |dir|
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.0
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-09 00:00:00.000000000 Z
11
+ date: 2026-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake