Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,82 @@ This project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

### Fixed
* **BREAKING: Generator folder structure**: Fixed install generator to create `e2e_helper.rb` and `app_commands/` at the install folder root (e.g., `e2e/`) instead of inside the framework subdirectory (e.g., `e2e/cypress/`). This ensures compatibility between Cypress/Playwright config file location and middleware expectations. [#201]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add missing link reference definition.

Line 11 references [#201] but the link definition is missing at the bottom of the file.

Add the following link definition near line 515 (after the PR references):

[#201]: https://github.com/shakacode/cypress-playwright-on-rails/issues/201
🤖 Prompt for AI Agents
In CHANGELOG.md around line 11 the reference "[#201]" is used but the
corresponding link reference definition is missing at the bottom of the file;
add the link definition line for PR/issue 201 (pointing to the GitHub issue URL)
after the PR references section near line 515 so the bracketed reference
resolves correctly.


### Migration Guide for Folder Structure Change

#### Breaking Change Notice
If you previously ran the install generator (versions prior to 1.20.0), the file structure created was incorrect. The generator placed helper and command files in the framework subdirectory when they should be at the install folder root.

**Old (Incorrect) Structure:**
```
e2e/
cypress.config.js
cypress/
e2e_helper.rb ← Wrong location
app_commands/ ← Wrong location
support/
e2e/
```

**New (Correct) Structure:**
```
e2e/
cypress.config.js
e2e_helper.rb ← Correct location
app_commands/ ← Correct location
fixtures/
vcr_cassettes/ ← VCR cassettes also at root
cypress/
support/
e2e/
```

#### How to Migrate

**Option 1: Fresh Installation (Recommended for new projects)**
```bash
# Remove old structure
rm -rf e2e/

# Re-run generator
bin/rails g cypress_on_rails:install --force
```

**Option 2: Manual Migration (For existing projects with custom code)**
```bash
# Move files to correct location
mv e2e/cypress/e2e_helper.rb e2e/
mv e2e/cypress/app_commands e2e/

# Update VCR cassettes path if using VCR
mv e2e/cypress/fixtures e2e/

# Verify your initializer has the correct path
# Should be: c.install_folder = File.expand_path("#{__dir__}/../../e2e")
# Not: c.install_folder = File.expand_path("#{__dir__}/../../e2e/cypress")
```

**Option 3: Update Initializer Only (Quick fix, not recommended)**
If you cannot migrate files immediately, you can temporarily update your initializer:
```ruby
# config/initializers/cypress_on_rails.rb
c.install_folder = File.expand_path("#{__dir__}/../../e2e/cypress")
```
However, this means Cypress may have issues finding config files. We recommend migrating to the correct structure.

#### Why This Change?
The middleware expects to find `e2e_helper.rb` at `#{install_folder}/e2e_helper.rb` and commands at `#{install_folder}/app_commands/`. Meanwhile, Cypress/Playwright expect config files at the install_folder root when using `--project` flag. The previous structure created a conflict where these requirements couldn't both be satisfied.

#### Testing Your Migration
After migrating, verify:
1. Run `bin/rails cypress:open` or `bin/rails playwright:open` - should open successfully
2. Run a test that uses app commands - should execute without "file not found" errors
3. Check that VCR cassettes (if used) are being created/loaded correctly

---

## [1.19.0] - 2025-10-01

### Added
Expand Down
60 changes: 47 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,17 +134,52 @@ bin/rails g cypress_on_rails:install --install_with=skip
bin/rails g cypress_on_rails:install --install_with=skip
```

The generator modifies/adds the following files/directory in your application:
* `config/initializers/cypress_on_rails.rb` used to configure Cypress on Rails
* `e2e/cypress/integration/` contains your cypress tests
* `e2e/cypress/support/on-rails.js` contains Cypress on Rails support code
* `e2e/cypress/e2e_helper.rb` contains helper code to require libraries like factory_bot
* `e2e/cypress/app_commands/` contains your scenario definitions
* `e2e/playwright/e2e/` contains your playwright tests
* `e2e/playwright/support/on-rails.js` contains Playwright on Rails support code

If you are not using `database_cleaner` look at `e2e/cypress/app_commands/clean.rb`.
If you are not using `factory_bot` look at `e2e/cypress/app_commands/factory_bot.rb`.
The generator creates the following structure in your application:

**For Cypress:**
```
e2e/
cypress.config.js # Cypress configuration
e2e_helper.rb # Helper code for factory_bot, database_cleaner, etc.
app_commands/ # Your custom commands and scenarios
clean.rb
factory_bot.rb
scenarios/
basic.rb
fixtures/
vcr_cassettes/ # VCR recordings (if using VCR)
cypress/
support/
index.js
commands.js
on-rails.js # Cypress on Rails support code
e2e/
rails_examples/ # Example tests
```

**For Playwright:**
```
e2e/
playwright.config.js # Playwright configuration
e2e_helper.rb # Helper code for factory_bot, database_cleaner, etc.
app_commands/ # Your custom commands and scenarios (shared with Cypress)
fixtures/
vcr_cassettes/ # VCR recordings (if using VCR)
playwright/
support/
index.js
on-rails.js # Playwright on Rails support code
e2e/
rails_examples/ # Example tests
```

**Additional files:**
* `config/initializers/cypress_on_rails.rb` - Configuration for Cypress on Rails

**Important:** Note that `e2e_helper.rb` and `app_commands/` are at the root of the install folder (e.g., `e2e/`), NOT inside the framework subdirectory (e.g., `e2e/cypress/`). This allows both Cypress and Playwright to share the same commands and helpers when using both frameworks.

If you are not using `database_cleaner` look at `e2e/app_commands/clean.rb`.
If you are not using `factory_bot` look at `e2e/app_commands/factory_bot.rb`.

Now you can create scenarios and commands that are plain Ruby files that get loaded through middleware, the ruby sky is your limit.

Expand Down Expand Up @@ -448,8 +483,7 @@ Add your VCR configuration to your `config/cypress_on_rails.rb`
c.vcr_options = {
hook_into: :webmock,
default_cassette_options: { record: :once },
# It's possible to override cassette_library_dir using install_folder
cassette_library_dir: File.expand_path("#{__dir__}/../../spec/cypress/fixtures/vcr_cassettes")
cassette_library_dir: File.expand_path("#{__dir__}/../../e2e/fixtures/vcr_cassettes")
}
```

Expand Down
20 changes: 20 additions & 0 deletions lib/cypress_on_rails/command_executor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,26 @@ def self.perform(file,command_options = nil)
def self.load_e2e_helper
e2e_helper_file = "#{configuration.install_folder}/e2e_helper.rb"
cypress_helper_file = "#{configuration.install_folder}/cypress_helper.rb"

# Check for old structure (files in framework subdirectory)
old_cypress_location = "#{configuration.install_folder}/cypress/e2e_helper.rb"
old_playwright_location = "#{configuration.install_folder}/playwright/e2e_helper.rb"

if File.exist?(old_cypress_location) || File.exist?(old_playwright_location)
old_location = File.exist?(old_cypress_location) ? old_cypress_location : old_playwright_location
logger.warn "=" * 80
logger.warn "DEPRECATION WARNING: Old folder structure detected!"
logger.warn "Found e2e_helper.rb at: #{old_location}"
logger.warn "This file should be at: #{e2e_helper_file}"
logger.warn ""
logger.warn "The generator now creates e2e_helper.rb and app_commands/ at the install_folder"
logger.warn "root, not inside the framework subdirectory."
logger.warn ""
logger.warn "To fix this, run: mv #{old_location} #{e2e_helper_file}"
logger.warn "See CHANGELOG.md for full migration guide."
logger.warn "=" * 80
end

if File.exist?(e2e_helper_file)
Kernel.require e2e_helper_file
elsif File.exist?(cypress_helper_file)
Expand Down
4 changes: 2 additions & 2 deletions lib/generators/cypress_on_rails/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ def install_framework

def add_initial_files
template "config/initializers/cypress_on_rails.rb.erb", "config/initializers/cypress_on_rails.rb"
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"
template "spec/e2e/e2e_helper.rb.erb", "#{options.install_folder}/e2e_helper.rb"
directory 'spec/e2e/app_commands', "#{options.install_folder}/app_commands"
if options.framework == 'cypress'
copy_file "spec/cypress/support/on-rails.js", "#{options.install_folder}/cypress/support/on-rails.js"
directory 'spec/cypress/e2e/rails_examples', "#{options.install_folder}/cypress/e2e/rails_examples"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
if defined?(CypressOnRails)
CypressOnRails.configure do |c|
c.api_prefix = "<%= options.api_prefix %>"
c.install_folder = File.expand_path("#{__dir__}/../../<%= options.install_folder %>/<%= options.framework %>")
c.install_folder = File.expand_path("#{__dir__}/../../<%= options.install_folder %>")
# WARNING!! CypressOnRails can execute arbitrary ruby code
# please use with extra caution if enabling on hosted servers or starting your local server on 0.0.0.0
c.use_middleware = !Rails.env.production?
Expand All @@ -12,7 +12,7 @@ if defined?(CypressOnRails)
<% unless options.experimental %># <% end %> c.vcr_options = {
<% 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")
Copy link

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.

Suggested change
<% 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).

<% unless options.experimental %># <% end %> }
c.logger = Rails.logger

Expand Down
Loading