-
-
Notifications
You must be signed in to change notification settings - Fork 62
Fix generator folder structure for install (#201) #203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
The generator was creating e2e_helper.rb and app_commands inside the framework subdirectory (e.g., e2e/cypress/app_commands), but they should be at the install_folder root level (e.g., e2e/app_commands). Changes: - Move e2e_helper.rb from install_folder/framework/ to install_folder/ - Move app_commands/ from install_folder/framework/ to install_folder/ - Update initializer template to set install_folder without framework path - Update VCR cassette path to use install_folder directly This ensures: 1. Cypress/Playwright can find their config files via --project flag 2. Middleware can find e2e_helper.rb and app_commands at install_folder 3. Both frameworks can share the same helper and commands if needed Fixes #201 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
WalkthroughRemoves the framework subdirectory from generator output and initializer template paths so e2e_helper.rb, app_commands, and VCR cassette paths are placed directly under the configured install_folder rather than under an additional framework directory. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Dev as Developer
participant Gen as InstallGenerator
participant FS as Filesystem
participant App as RailsApp
Dev->>Gen: rails g cypress_on_rails:install [framework, install_folder]
Gen->>FS: create files under <install_folder>/e2e_helper.rb
Gen->>FS: create dir <install_folder>/app_commands/...
Gen->>FS: create initializer config/initializers/cypress_on_rails.rb (install_folder without framework)
note over Gen,FS: Generator no longer nests files under a framework subdirectory
Dev->>App: rails cypress:run / cypress:open
App->>FS: read initializer c.install_folder and vcr_options (direct install_folder paths)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 RuboCop (1.81.1)spec/generators/install_generator_spec.rbCould not find gem 'rspec' in locally installed gems. ... [truncated 270 characters] ... fig_loader_resolver.rb:76:in Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
lib/generators/cypress_on_rails/install_generator.rb
(1 hunks)lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb
(2 hunks)
🔇 Additional comments (2)
lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb (1)
4-4
: LGTM: install_folder path simplified correctly.The removal of the framework subdirectory from install_folder is correct and fixes the configuration issue. Both Cypress/Playwright can now find their config files via
--project e2e
, and middleware can locate shared files at the same root.lib/generators/cypress_on_rails/install_generator.rb (1)
45-46
: Generator and middleware paths now match
e2e_helper.rb
andapp_commands
are placed at theinstall_folder
root, satisfyingCommandExecutor.load_e2e_helper
andMiddleware#file_path
.
<% unless options.experimental %># <% end %> hook_into: :webmock, | ||
<% unless options.experimental %># <% end %> default_cassette_options: { record: :once }, | ||
<% unless options.experimental %># <% end %> cassette_library_dir: File.expand_path("#{__dir__}/../../<%= options.install_folder %>/<%= options.framework %>/fixtures/vcr_cassettes") | ||
<% unless options.experimental %># <% end %> cassette_library_dir: File.expand_path("#{__dir__}/../../<%= options.install_folder %>/fixtures/vcr_cassettes") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
VCR cassettes now shared across frameworks.
The cassette_library_dir path change moves VCR cassettes from framework-specific directories (e.g., e2e/cypress/fixtures/vcr_cassettes
) to a shared location (e2e/fixtures/vcr_cassettes
). Since VCR cassettes record framework-agnostic HTTP interactions, this sharing is logical and reduces duplication.
Verify that cassette sharing works correctly across frameworks:
🏁 Script executed:
#!/bin/bash
# Description: Check for any code that might expect framework-specific cassette paths
# Search for VCR cassette path references
echo "=== Checking VCR cassette path usage ==="
rg -n -A3 -B3 'vcr_cassettes|cassette_library_dir' --type=rb
# Look for framework-specific fixture paths
echo -e "\n=== Checking for framework-specific fixture references ==="
rg -n 'fixtures.*cypress|fixtures.*playwright' --type=rb
Length of output: 154
🏁 Script executed:
#!/bin/bash
echo "=== Checking VCR cassette path usage ==="
rg -n -A3 -B3 'cassette_library_dir|vcr_cassettes'
echo
echo "=== Checking for framework-specific fixture references ==="
rg -n -C3 'cypress/fixtures/vcr_cassettes'
rg -n -C3 'playwright/fixtures/vcr_cassettes'
Length of output: 7365
Update README.md example for cassette_library_dir
Replace the framework-specific path in README.md (line 452)
- cassette_library_dir: File.expand_path("#{__dir__}/../../spec/cypress/fixtures/vcr_cassettes")
+ cassette_library_dir: File.expand_path("#{__dir__}/../../spec/fixtures/vcr_cassettes")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
<% unless options.experimental %># <% end %> cassette_library_dir: File.expand_path("#{__dir__}/../../<%= options.install_folder %>/fixtures/vcr_cassettes") | |
cassette_library_dir: File.expand_path("#{__dir__}/../../spec/fixtures/vcr_cassettes") |
🤖 Prompt for AI Agents
In
lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb
around line 15, the template uses a generic cassette_library_dir that references
the install_folder; update README.md (around line 452) to replace the current
framework-specific cassette path with the generic form used in the template so
it points to the fixtures/vcr_cassettes under the gem/install folder (i.e.,
remove framework-specific directory names and use the relative path pattern that
mirrors the template's install_folder location).
Created generator tests to verify: - Correct file structure creation (e2e_helper.rb and app_commands at install_folder root) - Framework-specific files in subdirectories (cypress/ or playwright/) - Initializer configuration with correct install_folder path - Custom install_folder option support - Both Cypress and Playwright framework support - Middleware and framework compatibility Tests ensure the generator creates files where the middleware expects them (install_folder/e2e_helper.rb, install_folder/app_commands/) while keeping framework-specific files in subdirectories. All 17 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Pull Request Review: Fix generator folder structure for install (#201)SummaryThis PR fixes a critical path configuration issue in the generator that was causing conflicts between where files are created and where the middleware/Cypress expects to find them. The fix ensures consistent behavior between the generator and runtime components. ✅ Strengths1. Correct Problem IdentificationThe PR correctly identifies and fixes the root cause described in issue #201:
2. Minimal, Focused ChangesThe PR makes only the necessary changes:
3. Excellent DocumentationThe PR description is exemplary:
4. Backward Compatibility MaintainedThe framework-specific files (support, e2e examples) remain in their framework subdirectories:
This allows both frameworks to share common resources ( 🔍 Areas for Consideration1. Migration Path for Existing UsersSeverity: Medium Existing installations will have files at the old locations (
Suggested addition to CHANGELOG.md: ## Breaking Changes
- The generator now creates `e2e_helper.rb` and `app_commands/` at the install folder root instead of inside the framework subdirectory
- **Migration required**: Move files from `e2e/cypress/` to `e2e/` and update `install_folder` in your initializer to `e2e` instead of `e2e/cypress` 2. Test CoverageSeverity: Medium I don't see automated tests for the generator behavior. Consider adding tests that verify:
Example test structure: # spec/generators/install_generator_spec.rb
RSpec.describe CypressOnRails::InstallGenerator do
it "creates e2e_helper.rb at install folder root" do
run_generator
expect(File).to exist("e2e/e2e_helper.rb")
expect(File).not_to exist("e2e/cypress/e2e_helper.rb")
end
it "creates app_commands at install folder root" do
run_generator
expect(Dir).to exist("e2e/app_commands")
expect(Dir).not_to exist("e2e/cypress/app_commands")
end
end 3. VCR Cassette Path UpdateObservation: Good catch! The PR correctly updates the VCR cassette library directory path (line 15 in the template). This is easy to miss but important for consistency. 🎯 Code Quality AssessmentBest Practices: ✅ Excellent
Potential Bugs: ✅ None identified
Performance: ✅ No impact
Security: ✅ No concerns
📋 Test Plan ReviewThe PR includes a good test plan. I recommend verifying:
🎉 ConclusionRecommendation: Approve with minor suggestions This is a well-executed fix that addresses a real user pain point. The changes are minimal, focused, and correct. The main areas for improvement are:
The fix properly aligns the generator output with runtime expectations, and the PR description demonstrates excellent understanding of the problem space. Great work on identifying and fixing this issue! 🚀 Review completed with analysis of codebase architecture, middleware expectations, and user-reported issues. |
Comprehensive code review posted - see full details in the comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (5)
spec/generators/install_generator_spec.rb (5)
16-16
: Consider removing ineffective mock.The
Dir.pwd
mock may be unnecessary since Thor generators use thedestination_root
explicitly set in the options hash (line 193). This mock likely has no effect on the generator's behavior and could be removed to simplify the test setup.- # Mock the generator's destination_root - allow(Dir).to receive(:pwd).and_return(destination_root) -
34-41
: Add negative assertions and use flexible string matching.Consider these improvements to strengthen the test:
- Add negative assertions to verify files are NOT created in the old wrong locations (e.g.,
e2e/cypress/e2e_helper.rb
should not exist).- Use regex or
match
instead of exact string matching to make the test more resilient to formatting changes.Apply this diff to add a negative assertion:
it 'creates the initializer with correct install_folder path' do initializer_path = File.join(destination_root, 'config', 'initializers', 'cypress_on_rails.rb') expect(File).to exist(initializer_path) content = File.read(initializer_path) # Should point to e2e, not e2e/cypress - expect(content).to include('c.install_folder = File.expand_path("#{__dir__}/../../e2e")') + expect(content).to match(/c\.install_folder\s*=\s*File\.expand_path\(["']#{__dir__}\/\.\.\/\.\.\/e2e["']\)/) + expect(content).not_to include('e2e/cypress') end
48-56
: Add negative assertions to verify old structure is not created.The PR objective is to fix the folder structure by moving files from
e2e/cypress/
toe2e/
. Adding negative assertions that verify files do NOT exist in the old wrong locations would strengthen confidence that the fix is complete.Apply this diff:
it 'creates e2e_helper.rb at install_folder root' do helper_path = File.join(destination_root, 'e2e', 'e2e_helper.rb') expect(File).to exist(helper_path) + + # Verify helper is NOT in the old wrong location + old_wrong_path = File.join(destination_root, 'e2e', 'cypress', 'e2e_helper.rb') + expect(File).not_to exist(old_wrong_path) end it 'creates app_commands directory at install_folder root' do commands_path = File.join(destination_root, 'e2e', 'app_commands') expect(File).to be_directory(commands_path) + + # Verify app_commands is NOT in the old wrong location + old_wrong_path = File.join(destination_root, 'e2e', 'cypress', 'app_commands') + expect(File).not_to exist(old_wrong_path) end
130-182
: Consider adding VCR cassette path test.The PR summary mentions "VCR cassette path updated to use install_folder directly." Consider adding a test to verify the VCR configuration in the generated initializer points to the correct location.
Add a test like this:
it 'configures VCR cassette_library_dir correctly in initializer' do initializer_path = File.join(destination_root, 'config', 'initializers', 'cypress_on_rails.rb') content = File.read(initializer_path) # VCR should use install_folder directly, not a framework subdirectory expect(content).to match(/cassette_library_dir.*install_folder/) expect(content).not_to match(/cassette_library_dir.*cypress/) end
26-105
: Consider using shared examples to reduce duplication.The Cypress and Playwright test suites have significant overlap. You could extract common assertions into shared examples to reduce duplication and make the tests more maintainable.
Example refactor:
shared_examples 'creates files at install_folder root' do |framework| it 'creates the initializer with correct install_folder path' do initializer_path = File.join(destination_root, 'config', 'initializers', 'cypress_on_rails.rb') expect(File).to exist(initializer_path) content = File.read(initializer_path) expect(content).to include('c.install_folder = File.expand_path("#{__dir__}/../../e2e")') end it 'creates e2e_helper.rb at install_folder root' do helper_path = File.join(destination_root, 'e2e', 'e2e_helper.rb') expect(File).to exist(helper_path) end it 'creates app_commands directory at install_folder root' do commands_path = File.join(destination_root, 'e2e', 'app_commands') expect(File).to be_directory(commands_path) end end describe 'with default options (cypress framework, e2e folder)' do before { run_generator([], {}) } include_examples 'creates files at install_folder root', 'cypress' it 'creates cypress config at install_folder root' do config_path = File.join(destination_root, 'e2e', 'cypress.config.js') expect(File).to exist(config_path) end # ... cypress-specific tests end describe 'with playwright framework' do before { run_generator([], { framework: 'playwright' }) } include_examples 'creates files at install_folder root', 'playwright' it 'creates playwright config at install_folder root' do config_path = File.join(destination_root, 'e2e', 'playwright.config.js') expect(File).to exist(config_path) end # ... playwright-specific tests end
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
spec/generators/install_generator_spec.rb
(1 hunks)
🔇 Additional comments (1)
spec/generators/install_generator_spec.rb (1)
1-199
: Well-structured test suite with good coverage.This test suite effectively validates the PR's core objective: ensuring files are created at the install_folder root rather than in framework subdirectories. The tests are comprehensive, well-organized, and use appropriate isolation techniques with temporary directories and mocking.
The structure clearly validates:
- Correct initializer configuration
- Proper placement of e2e_helper.rb and app_commands at install_folder root
- Framework-specific files in appropriate subdirectories
- Middleware and framework compatibility
Code Review SummaryThis PR successfully addresses issue #201 by fixing the generator to create the correct folder structure. The changes are well-designed and properly tested. Overall, this is a high-quality PR that solves a real structural problem. ✅ Strengths1. Clear Problem-Solution Design
2. Minimal, Focused Changes
3. Excellent Test Coverage
4. Good Documentation
|
🔍 Code Quality ReviewGenerator Changes (install_generator.rb:45-46) The changes correctly move e2e_helper.rb and app_commands/ from the framework subdirectory to the install_folder root, which aligns perfectly with how the middleware expects to find them. Before: template "spec/e2e/e2e_helper.rb.erb", "#{options.install_folder}/#{options.framework}/e2e_helper.rb"
directory "spec/e2e/app_commands", "#{options.install_folder}/#{options.framework}/app_commands" After: template "spec/e2e/e2e_helper.rb.erb", "#{options.install_folder}/e2e_helper.rb"
directory "spec/e2e/app_commands", "#{options.install_folder}/app_commands" Initializer Changes (cypress_on_rails.rb.erb:4,15) The initializer now correctly sets install_folder without the framework path, making it consistent with its purpose as the root location. This ensures:
|
🛡️ Security Analysis✅ No security concerns identified:
⚡ Performance Considerations✅ No performance impact:
📋 Test Coverage AssessmentExcellent coverage across:
Tests verify:
|
🐛 Potential Issues & RecommendationsMinor: Test Setup Mocking The test uses allow_any_instance_of which works fine but consider using instance_double for better test isolation in future tests. Important: Migration Path for Existing Users Existing users who already ran the old generator will have files in the wrong location. Consider:
Example migration steps users might need: # Move files from e2e/cypress/ to e2e/
mv e2e/cypress/e2e_helper.rb e2e/
mv e2e/cypress/app_commands e2e/
# Update config/initializers/cypress_on_rails.rb
# Change: c.install_folder = File.expand_path("#{__dir__}/../../e2e/cypress")
# To: c.install_folder = File.expand_path("#{__dir__}/../../e2e") 🎯 Final Recommendations
Final Verdict✅ APPROVED - This is a well-executed fix with excellent test coverage. The code quality is high, the changes are minimal and focused, and the solution correctly addresses the architectural issue. The only suggestion is to consider the migration path for existing users, but this does not block the PR from merging. Great work! 🎉 |
Summary
e2e_helper.rb
andapp_commands/
at the install folder root instead of inside the framework subdirectoryinstall_folder
without the framework pathProblem
After running
bin/rails g cypress_on_rails:install
, the generator created this structure:But the middleware expects to find
e2e_helper.rb
andapp_commands/
at#{install_folder}/
, and the Cypress/Playwright commands run with--project #{install_folder}
expecting the config file there.This caused conflicts where:
install_folder = e2e/cypress
(to find e2e_helper.rb)cypress.config.js
at that locatione2e
made Cypress work but broke the middlewareSolution
Changed the generator to create the correct structure:
Now:
install_folder
points toe2e
(note2e/cypress
)--project e2e
e2e/e2e_helper.rb
ande2e/app_commands/
Test plan
Fixes #201
🤖 Generated with Claude Code
Summary by CodeRabbit