Skip to content
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

VCR use_cassette middleware #167

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open

VCR use_cassette middleware #167

wants to merge 22 commits into from

Conversation

MUTOgen
Copy link

@MUTOgen MUTOgen commented Jul 7, 2024

WIP

Summary by CodeRabbit

  • New Features

    • Enhanced configuration options for VCR middleware, allowing for more flexible testing scenarios.
    • Introduced middleware for managing VCR cassette operations via designated HTTP endpoints.
    • Added a custom command for mocking GraphQL requests in Cypress.
    • Added new configuration options for VCR in the initializer file.
    • Updated the README with detailed instructions for both basic and insert/eject VCR setup.
  • Bug Fixes

    • Added a specific version of the bigdecimal gem to prevent runtime errors.
  • Tests

    • Implemented comprehensive tests for UseCassetteMiddleware and InsertEjectMiddleware to ensure correct functionality and error handling.
  • Documentation

    • Expanded the README with detailed instructions for VCR setup and usage.
    • Updated comments in configuration files to guide users on using VCR with GraphQL.
    • Enhanced documentation for integrating Cypress and Playwright with Ruby on Rails applications.

@MUTOgen MUTOgen self-assigned this Jul 7, 2024
Copy link

coderabbitai bot commented Jul 7, 2024

Walkthrough

The changes in this pull request enhance the Cypress on Rails framework by introducing new configuration options for VCR middleware, specifically through the Configuration class and middleware classes. Key additions include attributes for controlling VCR usage, new middleware for inserting and ejecting cassettes, and helper methods for managing VCR operations. The modifications also include RSpec tests to validate the functionality of the new middleware components. Overall, these changes aim to provide more flexibility and control over VCR usage in testing scenarios.

Changes

File Path Change Summary
lib/cypress_on_rails/configuration.rb Added attributes use_vcr_use_cassette_middleware and vcr_options, updated reset method, and created alias methods.
lib/cypress_on_rails/railtie.rb Added conditional middleware configuration for UseCassetteMiddleware based on use_vcr_use_cassette_middleware?.
lib/cypress_on_rails/vcr/insert_eject_middleware.rb Introduced InsertEjectMiddleware class for handling VCR cassette management via HTTP endpoints.
lib/cypress_on_rails/vcr/middleware_helpers.rb Added MiddlewareHelpers module with methods for VCR configuration and cassette library directory management.
lib/cypress_on_rails/vcr/use_cassette_middleware.rb Defined UseCassetteMiddleware class for integrating VCR functionality into Rack applications.
lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb Added commented-out options for VCR middleware configuration.
lib/generators/cypress_on_rails/templates/spec/cypress/support/on-rails.js Added comment for GraphQL mocking with cy.mockGraphQL().
spec/cypress_on_rails/vcr/use_cassette_middleware_spec.rb Introduced tests for UseCassetteMiddleware to validate VCR cassette handling.
spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb Added tests for InsertEjectMiddleware covering insert/eject functionality and error handling.
specs_e2e/rails_4_2/Gemfile Added dependency for bigdecimal gem version 1.3.5 to resolve compatibility issues.

Possibly related issues

  • VCR with use_cassette #160: The changes in this PR enhance VCR functionality, which aligns with the issue's objective of integrating the use_cassette wrapper into the current VCR cassette implementation.

🐰 In the meadow, we hop and play,
New cassettes are here to stay!
With middleware to guide our way,
VCR's magic brightens the day.
So let’s record and then replay,
In testing fields, we’ll leap and sway! 🌼✨

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. This feature will be included in our Pro Plan when released.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

cypress bot commented Jul 7, 2024

cypress-on-rails    Run #133

Run Properties:  status check passed Passed #133  •  git commit 1bc82b6ae6 ℹ️: Merge 5afef6afa8a6885d81701fcdc3dcd1334796cc81 into dcea71969846e26d05e073a56f3c...
Project cypress-on-rails
Branch Review new-vcr-middleware
Run status status check passed Passed #133
Run duration 00m 10s
Commit git commit 1bc82b6ae6 ℹ️: Merge 5afef6afa8a6885d81701fcdc3dcd1334796cc81 into dcea71969846e26d05e073a56f3c...
Committer Anton
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 10
View all changes introduced in this branch ↗︎

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Outside diff range and nitpick comments (3)
lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb (1)

9-11: Consider enabling the new VCR middleware configuration.

The new configuration options for VCR middleware are commented out. Ensure to enable them as needed and provide appropriate documentation.

-  # c.use_vcr_use_cassette_middleware = !Rails.env.production?
-  # c.vcr_use_cassette_mode = :once # Use to choose VCR record mode (:new_episodes by default)
+  c.use_vcr_use_cassette_middleware = !Rails.env.production?
+  c.vcr_use_cassette_mode = :once # Use to choose VCR record mode (:new_episodes by default)
lib/generators/cypress_on_rails/templates/spec/cypress/support/commands.js (1)

26-47: Consider enabling the new GraphQL commands.

The new commands for GraphQL usage are commented out. Ensure to enable them as needed and provide appropriate documentation.

-  // Cypress.Commands.add('mockGraphQL', () => {
-  //   cy.on('window:before:load', (win) => {
-  //     const originalFetch = win.fetch;
-  //     const fetch = (path, options, ...rest) => {
-  //       if (options && options.body) {
-  //         try {
-  //           const body = JSON.parse(options.body);
-  //           if (body.operationName) {
-  //             return originalFetch(`${path}?operation=${body.operationName}`, options, ...rest);
-  //           }
-  //         } catch (e) {
-  //           return originalFetch(path, options, ...rest);
-  //         }
-  //       }
-  //       return originalFetch(path, options, ...rest);
-  //     };
-  //     cy.stub(win, 'fetch', fetch);
-  //   });
-  // });
+  Cypress.Commands.add('mockGraphQL', () => {
+    cy.on('window:before:load', (win) => {
+      const originalFetch = win.fetch;
+      const fetch = (path, options, ...rest) => {
+        if (options && options.body) {
+          try {
+            const body = JSON.parse(options.body);
+            if (body.operationName) {
+              return originalFetch(`${path}?operation=${body.operationName}`, options, ...rest);
+            }
+          } catch (e) {
+            return originalFetch(path, options, ...rest);
+          }
+        }
+        return originalFetch(path, options, ...rest);
+      };
+      cy.stub(win, 'fetch', fetch);
+    });
+  });
lib/generators/cypress_on_rails/templates/spec/cypress/support/on-rails.js (1)

50-50: Consider enabling the new GraphQL commands.

The new commands for GraphQL usage are commented out. Ensure to enable them as needed and provide appropriate documentation.

-  // cy.mockGraphQL(); // for GraphQL usage, see cypress/support/commands.rb
+  cy.mockGraphQL(); // for GraphQL usage, see cypress/support/commands.rb
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7dc7581 and 308eddd.

Files selected for processing (11)
  • lib/cypress_on_rails/configuration.rb (2 hunks)
  • lib/cypress_on_rails/railtie.rb (1 hunks)
  • lib/cypress_on_rails/vcr/base_middleware.rb (1 hunks)
  • lib/cypress_on_rails/vcr/insert_eject_middleware.rb (1 hunks)
  • lib/cypress_on_rails/vcr/use_cassette_middleware.rb (1 hunks)
  • lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb (1 hunks)
  • lib/generators/cypress_on_rails/templates/spec/cypress/support/commands.js (1 hunks)
  • lib/generators/cypress_on_rails/templates/spec/cypress/support/on-rails.js (1 hunks)
  • spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb (1 hunks)
  • spec/cypress_on_rails/vcr/use_cassette_middleware_spec.rb (1 hunks)
  • specs_e2e/rails_3_2/config/boot.rb (1 hunks)
Files skipped from review due to trivial changes (1)
  • specs_e2e/rails_3_2/config/boot.rb
Additional comments not posted (28)
lib/cypress_on_rails/railtie.rb (2)

12-14: Ensure Vcr::InsertEjectMiddleware is correctly integrated.

The middleware Vcr::InsertEjectMiddleware is integrated based on the use_vcr_middleware? configuration setting.

Ensure the Vcr::InsertEjectMiddleware is correctly implemented and tested.


15-17: Ensure Vcr::UseCassetteMiddleware is correctly integrated.

The middleware Vcr::UseCassetteMiddleware is integrated based on the use_vcr_use_cassette_middleware? configuration setting.

Ensure the Vcr::UseCassetteMiddleware is correctly implemented and tested.

lib/cypress_on_rails/vcr/base_middleware.rb (5)

11-13: Abstract method initialize should not be called directly.

The initialize method raises a NotImplementedError to prevent direct instantiation of BaseMiddleware.


15-17: Abstract method call should not be called directly.

The call method raises a NotImplementedError to prevent direct invocation on BaseMiddleware.


19-21: Lazy initialization of VCR configuration.

The vcr method lazily initializes the VCR configuration by calling configure_vcr.


25-31: VCR configuration method.

The configure_vcr method sets up the VCR configuration, including the cassette library directory.


33-36: Raise error for direct instantiation.

The raise_not_implemented method raises an error to indicate that BaseMiddleware should not be instantiated directly.

lib/cypress_on_rails/vcr/use_cassette_middleware.rb (5)

8-11: Ensure correct initialization of UseCassetteMiddleware.

The initialize method sets up the middleware with the provided app and VCR instance.


13-20: Handle VCR interactions with use_cassette.

The call method handles VCR interactions using the use_cassette method based on the request path.


24-26: Access configuration settings.

The configuration method returns the CypressOnRails configuration.


28-30: Access logger instance.

The logger method returns the logger instance from the configuration.


32-38: Fetch cassette name based on request path.

The fetch_request_cassette method determines the cassette name based on the request path and parameters.

lib/cypress_on_rails/configuration.rb (5)

9-9: New configuration option use_vcr_use_cassette_middleware.

The use_vcr_use_cassette_middleware option controls the use of VCR middleware.


12-12: New configuration option vcr_use_cassette_mode.

The vcr_use_cassette_mode option sets the VCR cassette recording mode.


30-30: Alias for use_vcr_use_cassette_middleware.

The alias use_vcr_use_cassette_middleware? allows querying the configuration option.


37-37: Reset configuration option use_vcr_use_cassette_middleware.

The reset method sets the default value for use_vcr_use_cassette_middleware to false.


40-40: Reset configuration option vcr_use_cassette_mode.

The reset method sets the default value for vcr_use_cassette_mode to :new_episodes.

spec/cypress_on_rails/vcr/use_cassette_middleware_spec.rb (1)

1-44: LGTM!

The new test cases for UseCassetteMiddleware are correctly implemented and cover necessary scenarios.

lib/cypress_on_rails/vcr/insert_eject_middleware.rb (4)

7-11: LGTM!

The initialize method correctly sets up the middleware with the application and VCR instance.


39-41: LGTM!

The parse_request_body method correctly parses the request body as JSON.


53-60: LGTM!

The handle_eject method correctly manages the ejection of VCR cassettes and handles errors.


62-68: LGTM!

The do_first_call method correctly handles the first call setup for VCR and WebMock.

spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb (6)

20-35: LGTM!

The test case correctly verifies the middleware's behavior for the /__e2e__/vcr/insert path.


37-46: LGTM!

The test case correctly verifies the middleware's behavior for the /__e2e__/vcr/insert path with the record option.


48-57: LGTM!

The test case correctly verifies the middleware's behavior for the /__e2e__/vcr/insert path with the match_requests_on option.


59-68: LGTM!

The test case correctly verifies the middleware's behavior for the /__e2e__/vcr/insert path with the serialize_with option.


70-79: LGTM!

The test case correctly verifies the middleware's behavior for the /__e2e__/vcr/insert path with the persist_with option.


82-96: LGTM!

The test case correctly verifies the middleware's behavior for the /__e2e__/vcr/eject path.

Copy link

@coderabbitai coderabbitai bot left a 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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 308eddd and 97b375b.

Files selected for processing (1)
  • lib/cypress_on_rails/vcr/insert_eject_middleware.rb (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • lib/cypress_on_rails/vcr/insert_eject_middleware.rb

@MUTOgen MUTOgen marked this pull request as draft July 7, 2024 18:46
@MUTOgen MUTOgen changed the title VCR use_cassette middleware [WIP] VCR use_cassette middleware Jul 7, 2024
@MUTOgen MUTOgen changed the title [WIP] VCR use_cassette middleware [WIP DO NOT MERGE] VCR use_cassette middleware Jul 7, 2024
end

def call(env)
return @app.call(env) if should_not_use_vcr?
Copy link
Author

Choose a reason for hiding this comment

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

This is a workaround to skip behavior if VCR is already in use (rspec, for example)

@justin808
Copy link
Member

@MUTOgen any word on getting this merged?

@MUTOgen MUTOgen changed the title [WIP DO NOT MERGE] VCR use_cassette middleware VCR use_cassette middleware Sep 19, 2024
@MUTOgen MUTOgen marked this pull request as ready for review September 19, 2024 20:06
@MUTOgen
Copy link
Author

MUTOgen commented Sep 19, 2024

@justin808 Yep, it should be ready for review now

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Outside diff range and nitpick comments (3)
README.md (1)

358-360: Looks good! Just a minor formatting suggestion.

The added content clearly explains the two modes of using VCR.

For consistency, consider using the same unordered list style (asterisk or dash) for both list items:

- - with separate insert/eject calls (more general, recommended way)
- - with use_cassette wrapper (supports only GraphQL integration)
+ * with separate insert/eject calls (more general, recommended way)
+ * with use_cassette wrapper (supports only GraphQL integration)
Tools
Markdownlint

359-359: Expected: asterisk; Actual: dash
Unordered list style

(MD004, ul-style)


360-360: Expected: asterisk; Actual: dash
Unordered list style

(MD004, ul-style)

lib/cypress_on_rails/vcr/base_middleware.rb (2)

26-26: Consider requiring 'vcr' at the top of the file for clarity

Requiring 'vcr' within the configure_vcr method delays the loading of the vcr gem until this method is called. For clarity and to ensure that missing dependencies are caught early, it's advisable to require all dependencies at the top of the file.

Apply this diff to move the require statement:

+require 'vcr'

module CypressOnRails
  module Vcr
    # Base abstract Middleware
    class BaseMiddleware
      include MiddlewareConfig

      # ... existing methods ...

      private

-     def configure_vcr
-       require 'vcr'
+     def configure_vcr
        VCR.configure do |config|
          config.cassette_library_dir = cassette_library_dir
        end
        VCR
      end

39-39: Typographical correction in error message

In the error message, "can not" should be "cannot" to adhere to standard spelling conventions.

Apply this diff to correct the typo:

def raise_not_implemented
  raise NotImplementedError,
-        'BaseMiddleware can not be initialized directly, use InsertEjectMiddleware or UseCassetteMiddleware'
+        'BaseMiddleware cannot be initialized directly, use InsertEjectMiddleware or UseCassetteMiddleware'
end
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 97b375b and 916ad59.

Files selected for processing (9)
  • README.md (3 hunks)
  • lib/cypress_on_rails/configuration.rb (2 hunks)
  • lib/cypress_on_rails/railtie.rb (1 hunks)
  • lib/cypress_on_rails/vcr/base_middleware.rb (1 hunks)
  • lib/cypress_on_rails/vcr/use_cassette_middleware.rb (1 hunks)
  • lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb (1 hunks)
  • lib/generators/cypress_on_rails/templates/spec/cypress/support/on-rails.js (1 hunks)
  • spec/cypress_on_rails/vcr/use_cassette_middleware_spec.rb (1 hunks)
  • specs_e2e/rails_4_2/Gemfile (1 hunks)
Files skipped from review due to trivial changes (1)
  • lib/generators/cypress_on_rails/templates/spec/cypress/support/on-rails.js
Additional context used
Markdownlint
README.md

359-359: Expected: asterisk; Actual: dash
Unordered list style

(MD004, ul-style)


360-360: Expected: asterisk; Actual: dash
Unordered list style

(MD004, ul-style)

rubocop
lib/cypress_on_rails/vcr/use_cassette_middleware.rb

[warning] 7-10: Call super to initialize state of the parent class.

(Lint/MissingSuper)

Additional comments not posted (20)
specs_e2e/rails_4_2/Gemfile (1)

6-8: LGTM! The change is well-documented and addresses a specific issue.

The addition of the bigdecimal gem with a specific version constraint is a good solution to address the NoMethodError issue related to the BigDecimal class. The comments provide a clear explanation of the purpose of the change and include a reference to a GitHub page for further guidance on selecting the appropriate version.

This change demonstrates good practices by:

  • Specifying a specific version constraint to ensure compatibility.
  • Providing clear comments explaining the purpose of the change.
  • Including a reference to a relevant resource for additional information.
lib/cypress_on_rails/railtie.rb (3)

12-13: LGTM! The new middleware enhances VCR functionality.

The Vcr::InsertEjectMiddleware replaces the previous VCRMiddleware. This new middleware likely handles the insertion and ejection of VCR cassettes, providing more granular control over VCR usage in the testing environment.

The change is conditional based on the use_vcr_middleware? configuration option, allowing flexibility in enabling or disabling this functionality.


15-17: Great addition! The new middleware enhances VCR cassette usage.

The introduction of the Vcr::UseCassetteMiddleware middleware, conditionally enabled by the new use_vcr_use_cassette_middleware? configuration option, adds a new layer of functionality for using VCR cassettes during tests.

This middleware likely handles the usage of VCR cassettes, providing more control and flexibility over how external requests are handled in the testing environment.

The conditional nature of this middleware allows users to enable or disable this functionality based on their specific testing needs.


Line range hint 1-23: Overall, the changes in this file are excellent! They enhance VCR functionality and provide more control over its usage.

The introduction of the Vcr::InsertEjectMiddleware and Vcr::UseCassetteMiddleware middleware classes, along with their corresponding configuration options, allows for more granular control over VCR usage in the testing environment.

These changes provide flexibility in enabling or disabling specific VCR functionalities based on the user's testing needs. The conditional nature of the middleware additions ensures that the functionality is only included when desired.

The code changes are well-structured, follow the existing code patterns, and integrate seamlessly with the existing codebase.

Great work on enhancing the VCR capabilities of the cypress_on_rails package!

lib/cypress_on_rails/configuration.rb (4)

9-9: LGTM!

The new attribute use_vcr_use_cassette_middleware is declared correctly using attr_accessor. The naming clearly conveys its purpose as a flag to control the usage of VCR's use_cassette middleware.


12-12: LGTM!

The new attribute vcr_record_mode is declared correctly using attr_accessor. The naming clearly conveys its purpose as a configuration for setting the record mode for VCR.


30-30: LGTM!

The alias method use_vcr_use_cassette_middleware? is defined correctly for the attribute use_vcr_use_cassette_middleware. The naming convention of appending ? is consistent with Ruby's conventions for predicate methods, making the code more readable.


37-37: LGTM!

The reset method is updated correctly to initialize the new attributes use_vcr_use_cassette_middleware and vcr_record_mode with appropriate default values:

  • use_vcr_use_cassette_middleware is set to false, disabling the usage of VCR's use_cassette middleware by default.
  • vcr_record_mode is set to :new_episodes, configuring VCR to record new interactions while replaying existing ones by default.

The changes ensure that the new attributes have consistent default values when the configuration is reset.

Also applies to: 40-40

lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb (1)

9-11: LGTM! The new configuration options provide flexibility for VCR middleware.

The added configuration options, use_vcr_use_cassette_middleware and vcr_record_mode, allow users to customize the behavior of VCR middleware in their Cypress tests.

  • use_vcr_use_cassette_middleware, when enabled, allows the use of the use_cassette wrapper, which can simplify the usage of VCR in tests by automatically handling the cassette lifecycle.
  • vcr_record_mode allows setting the VCR record mode, which determines how VCR records and replays HTTP interactions during tests. For example, setting it to :once would record interactions once and replay them in subsequent test runs.

By keeping these options commented out by default, the changes maintain backward compatibility and allow users to opt-in to the new functionality as needed.

spec/cypress_on_rails/vcr/use_cassette_middleware_spec.rb (4)

24-31: LGTM!

The test case correctly verifies the middleware's behavior when handling a GraphQL request. It ensures that the middleware returns the application response and invokes VCR with the appropriate cassette path and recording mode.


33-41: LGTM!

The test case correctly verifies the middleware's behavior when using the default request path cassette. It ensures that the middleware returns the application response and invokes VCR with the appropriate cassette path and recording mode based on the configuration.


43-54: LGTM!

The test case correctly verifies the middleware's behavior when the VCR cassette library directory does not match. It ensures that the middleware returns the application response without invoking VCR, as expected in this scenario.


56-69: Skip this test case.

The test case seems to have an inconsistency. It sets up the environment with VCR not defined, but still expects VCR to have received the use_cassette method. If VCR is not defined, the middleware should not invoke VCR at all. Please review and update the test case accordingly.

README.md (4)

387-393: LGTM!

The setup instructions for insert/eject mode are clear and the commented out configuration for use_cassette mode is a helpful reference.


423-436: Looks good!

The setup instructions for use_cassette mode are comprehensive and cover the necessary configuration steps.


438-461: Great addition!

The custom mockGraphQL command is a smart way to enable VCR to capture GraphQL requests by operation name. The code is well-structured and includes proper error handling.


463-475: Looks good!

The usage instructions clearly explain that no special calls are needed in Cypress scenarios when using VCR with use_cassette mode. It's helpful to mention that cassettes will be automatically recorded and saved.

lib/cypress_on_rails/vcr/base_middleware.rb (2)

11-17: Ensure subclasses properly implement 'initialize' and 'call' methods

Since BaseMiddleware is an abstract class with initialize and call methods raising NotImplementedError, ensure that all subclasses override these methods with concrete implementations to provide the intended functionality.

Run the following script to confirm that subclasses implement the required methods:

#!/bin/bash
# Description: Verify subclasses of BaseMiddleware implement 'initialize' and 'call' methods.

# Find all subclasses of BaseMiddleware
rg --type ruby 'class (\w+) < BaseMiddleware' -o -r '$1' | while read -r subclass; do
  echo "Checking $subclass..."
  # Check for 'def initialize' in subclass
  rg --type ruby -A 5 "class ${subclass} < BaseMiddleware" | rg 'def initialize' >/dev/null || echo "Warning: ${subclass} may not implement 'initialize'"
  # Check for 'def call' in subclass
  rg --type ruby -A 5 "class ${subclass} < BaseMiddleware" | rg 'def call' >/dev/null || echo "Warning: ${subclass} may not implement 'call'"
done

34-34: Verify that 'configuration' is accessible within the method

Ensure that the configuration method is defined and accessible within the context of cassette_library_dir. Since configuration is expected to be provided by MiddlewareConfig, verify that it is correctly included and initialized.

Run the following script to check for the definition of configuration:

Verification successful

'configuration' method is accessible in BaseMiddleware

The verification process confirms that the 'configuration' method is indeed accessible within the context of the 'cassette_library_dir' method in BaseMiddleware. Here's why:

  • BaseMiddleware includes the MiddlewareConfig module.
  • MiddlewareConfig defines the 'configuration' method, which returns CypressOnRails.configuration.
  • By including MiddlewareConfig, BaseMiddleware and its subclasses gain access to the 'configuration' method.

Therefore, the use of 'configuration.install_folder' in the code snippet is valid and should work as expected.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that 'configuration' method is defined in MiddlewareConfig.

# Test: Search for 'def configuration' within MiddlewareConfig module. Expect: Method definition exists.
rg --type ruby -A 5 -B 2 'module MiddlewareConfig' | rg 'def configuration'

Length of output: 1031


Script:

#!/bin/bash

# 1. Check BaseMiddleware class definition and MiddlewareConfig inclusion
echo "Checking BaseMiddleware class definition:"
rg --type ruby -A 5 "class BaseMiddleware"

echo "\nChecking if BaseMiddleware includes MiddlewareConfig:"
rg --type ruby "class BaseMiddleware" -A 10 | rg "include MiddlewareConfig"

# 2. Look for 'configuration' in MiddlewareConfig
echo "\nSearching for 'configuration' in MiddlewareConfig:"
rg --type ruby -A 5 "module MiddlewareConfig" | rg -A 5 "def configuration"

# 3. Examine BaseMiddleware for 'configuration' usage
echo "\nExamining BaseMiddleware for 'configuration' usage:"
rg --type ruby "class BaseMiddleware" -A 20 | rg "configuration"

# 4. Check for initializer in BaseMiddleware
echo "\nChecking for initializer in BaseMiddleware:"
rg --type ruby "class BaseMiddleware" -A 20 | rg "def initialize"

Length of output: 1623

lib/cypress_on_rails/vcr/use_cassette_middleware.rb (1)

13-13: Existing handling of VCR usage condition

As previously noted, the early return in call method serves as a workaround to skip behavior if VCR is already in use (e.g., with RSpec). This implementation is acceptable given the context.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (3)
lib/cypress_on_rails/vcr/middleware_helpers.rb (3)

9-12: LGTM: Well-structured initialize method with a minor suggestion.

The initialize method is well-designed, allowing for dependency injection of both the app and vcr instances. The default value of nil for vcr enables lazy initialization.

Consider adding a brief comment explaining the purpose of the app and vcr parameters for improved clarity:

# @param app [Object] The Rack application
# @param vcr [VCR, nil] Optional VCR instance for testing
def initialize(app, vcr = nil)
  @app = app
  @vcr = vcr
end

14-20: LGTM: Well-implemented vcr and cassette_library_dir methods with a suggestion for improvement.

The vcr method's lazy initialization is a good practice for performance. The cassette_library_dir method appropriately uses the configuration's install_folder to define the path for storing VCR cassettes.

Consider adding error handling to the cassette_library_dir method to ensure the install_folder is set:

def cassette_library_dir
  raise "Configuration install_folder is not set" if configuration.install_folder.nil?
  "#{configuration.install_folder}/fixtures/vcr_cassettes"
end

This will provide a more informative error message if the configuration is not properly set.


22-31: LGTM: Well-implemented configure_vcr method with suggestions for improvement.

The configure_vcr method is well-structured, with lazy loading of the VCR library and appropriate configuration of the cassette library directory.

Consider the following improvements:

  1. Add error handling for VCR library loading:
def configure_vcr
  begin
    require 'vcr'
  rescue LoadError
    raise "VCR library is not available. Please ensure it's properly installed."
  end
  # ... rest of the method
end
  1. Allow for more flexible VCR configuration:
def configure_vcr
  require 'vcr'
  VCR.configure do |config|
    config.cassette_library_dir = cassette_library_dir
    # Add more default configuration options here
    yield(config) if block_given?
  end
  VCR
end

This change allows users to pass a block with additional configuration options if needed.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 916ad59 and 218e3a4.

📒 Files selected for processing (3)
  • lib/cypress_on_rails/vcr/insert_eject_middleware.rb (1 hunks)
  • lib/cypress_on_rails/vcr/middleware_helpers.rb (1 hunks)
  • lib/cypress_on_rails/vcr/use_cassette_middleware.rb (1 hunks)
🔇 Additional comments (3)
lib/cypress_on_rails/vcr/middleware_helpers.rb (1)

1-8: LGTM: Appropriate module structure and configuration inclusion.

The module is correctly defined within the CypressOnRails::Vcr namespace, and the inclusion of MiddlewareConfig is appropriate for accessing configuration-related methods.

lib/cypress_on_rails/vcr/insert_eject_middleware.rb (2)

21-22: Fix potential race condition

The previous comment regarding a potential race condition is still applicable. Setting @first_call after calling do_first_call could lead to unintended behavior in a multi-threaded environment.


44-52: Add validation for request body

The earlier suggestion to validate the request body is still valid. Ensuring that body is an array with at least one element will prevent potential errors when accessing body[0] and body[1].

Comment on lines 36 to 41
rescue LoadError, ArgumentError => e
[501, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]]
end
Copy link

@coderabbitai coderabbitai bot Sep 27, 2024

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use appropriate HTTP status code for server errors

In the rescue clauses of handle_insert and handle_eject, 501 Not Implemented is used to indicate errors caused by LoadError or ArgumentError. The 501 status code implies that the server does not support the functionality required to fulfill the request, which may not accurately represent these error cases. Consider using 500 Internal Server Error to represent unexpected server errors more appropriately.

Apply this diff to correct the status code:

-rescue LoadError, ArgumentError => e
-  [501, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]]
+rescue LoadError, ArgumentError => e
+  [500, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]]

Also applies to: 59-61

Copy link
Collaborator

Choose a reason for hiding this comment

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

agree 👍🏽

Copy link

Choose a reason for hiding this comment

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

@grantspeelman Glad you agree!

(^・ω・^)

@justin808
Copy link
Member

@MUTOgen any updates?

@grantspeelman can you give us your thoughts?

Copy link
Collaborator

@grantspeelman grantspeelman left a comment

Choose a reason for hiding this comment

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

It all looks good to me.
Be interesting to see if this is viable in practice 👍🏽

Comment on lines 36 to 41
rescue LoadError, ArgumentError => e
[501, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]]
end
Copy link
Collaborator

Choose a reason for hiding this comment

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

agree 👍🏽

Comment on lines 59 to 60
rescue LoadError, ArgumentError => e
[501, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
rescue LoadError, ArgumentError => e
[501, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]]
rescue LoadError, ArgumentError => e
[500, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]]

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (2)
lib/cypress_on_rails/vcr/insert_eject_middleware.rb (1)

63-69: Log exceptions instead of suppressing them

In the do_first_call method, rescuing LoadError without any action (# nop) can make debugging difficult if an error occurs. Consider logging the exception to aid in troubleshooting.

Apply this diff to log the exception:

 rescue LoadError => e
-  # nop
+  logger.error "LoadError in do_first_call: #{e.message}"
spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb (1)

31-31: Add Trailing Commas to Multiline Arrays for Consistency

Adding a trailing comma after the last item of a multiline array enhances code consistency and makes future diffs cleaner.

Apply the following changes:

At line 31:

  expect(response).to eq([201,
                          { 'Content-Type' => 'application/json' },
-                         ['{"message":"OK"}']])
+                         ['{"message":"OK"}',]])

Similarly, add trailing commas at the end of multiline arrays at lines 43, 54, 65, 76, 89, 100, 115, 128, and 138.

[Style/TrailingCommaInArrayLiteral]

Also applies to: 43-43, 54-54, 65-65, 76-76, 89-89, 100-100, 115-115, 128-128, 138-138

🧰 Tools
🪛 rubocop

[convention] 31-31: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 218e3a4 and bd1dc92.

📒 Files selected for processing (2)
  • lib/cypress_on_rails/vcr/insert_eject_middleware.rb (1 hunks)
  • spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb (1 hunks)
🧰 Additional context used
🪛 rubocop
spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb

[convention] 6-166: Module has too many lines. [130/100]

(Metrics/ModuleLength)


[convention] 31-31: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 43-43: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 54-54: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 65-65: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 76-76: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 89-89: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 100-100: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 115-115: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 128-128: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 138-138: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)

🔇 Additional comments (2)
lib/cypress_on_rails/vcr/insert_eject_middleware.rb (2)

21-22: Potential race condition when setting @first_call

As previously noted, setting @first_call after calling do_first_call may lead to race conditions in multi-threaded environments. It's safer to set @first_call = true before calling do_first_call to prevent concurrent threads from executing do_first_call multiple times.

Apply this diff to fix the potential race condition:

-def call(env)
-  request = Rack::Request.new(env)
-  if request.path.start_with?('/__e2e__/vcr/insert')
-    configuration.tagged_logged { handle_insert(request) }
-  elsif request.path.start_with?('/__e2e__/vcr/eject')
-    configuration.tagged_logged { handle_eject }
-  else
-    do_first_call unless @first_call
+    unless @first_call
+      @first_call = true
+      do_first_call
+    end
     @app.call(env)
   end
 end

44-52: Validate cassette information in extract_cassette_info

As previously noted, there is no validation to ensure that body is an array with at least one element. Accessing body[0] without validation might raise an exception if body is nil or not in the expected format. Ensure that body is properly validated before extracting cassette information.

lib/cypress_on_rails/vcr/insert_eject_middleware.rb Outdated Show resolved Hide resolved
lib/cypress_on_rails/vcr/insert_eject_middleware.rb Outdated Show resolved Hide resolved
spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Outside diff range and nitpick comments (3)
spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb (2)

154-174: Minor improvement suggestion for "Other paths" tests.

The "Other paths" tests look good and cover the necessary scenarios. However, in the second test (lines 162-173), you're using aggregate_failures but not taking full advantage of it. Consider moving the expectations inside the loop to truly aggregate failures for each path. This would provide more detailed information if a test fails.

Here's a suggested improvement:

it 'runs app for various paths' do
  %w[/ /__e2e__/login command /e2e_command /].each do |path|
    env['PATH_INFO'] = path

    response = subject.call(env)

    aggregate_failures do
      expect(response).to eq([200, {}, ["app did #{path}"]])
      expect(vcr).to have_received(:turn_off!)
    end
  end
end

This change would report failures for each path separately, making it easier to identify which specific path(s) caused a test failure.


1-177: Address RuboCop style issues.

RuboCop has flagged a few style issues in this file:

  1. The module exceeds the recommended maximum line count (138 lines vs. 100 lines limit). Given the comprehensive nature of these tests, this may be acceptable. However, consider if any further refactoring (such as the shared examples suggested earlier) could help reduce the overall line count.

  2. There are multiple instances of missing trailing commas in multiline arrays. To improve consistency and make future additions easier, consider adding trailing commas to all multiline arrays in the file. For example:

expect(response).to eq([201,
                        { 'Content-Type' => 'application/json' },
                        ['{"message":"OK"}'],])

Addressing these style issues will improve the overall code quality and maintainability.

🧰 Tools
🪛 rubocop

[convention] 6-176: Module has too many lines. [138/100]

(Metrics/ModuleLength)


[convention] 31-31: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 43-43: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 54-54: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 65-65: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 76-76: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 89-89: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 100-100: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 111-111: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 125-125: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 138-138: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 148-148: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)

lib/cypress_on_rails/vcr/use_cassette_middleware.rb (1)

47-53: Consider sanitizing cassette names to ensure valid file paths.

In the fetch_request_cassette method, cassette names may include forward slashes (e.g., '/graphql/operationName'). This could lead to issues when VCR tries to save or retrieve cassette files, as some file systems may not handle slashes in file names as intended. Consider replacing slashes and other potentially problematic characters with safe alternatives.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between bd1dc92 and b5e5202.

📒 Files selected for processing (4)
  • lib/cypress_on_rails/vcr/insert_eject_middleware.rb (1 hunks)
  • lib/cypress_on_rails/vcr/middleware_helpers.rb (1 hunks)
  • lib/cypress_on_rails/vcr/use_cassette_middleware.rb (1 hunks)
  • spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/cypress_on_rails/vcr/insert_eject_middleware.rb
🧰 Additional context used
🪛 rubocop
spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb

[convention] 6-176: Module has too many lines. [138/100]

(Metrics/ModuleLength)


[convention] 31-31: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 43-43: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 54-54: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 65-65: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 76-76: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 89-89: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 100-100: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 111-111: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 125-125: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 138-138: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 148-148: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)

🔇 Additional comments (5)
lib/cypress_on_rails/vcr/middleware_helpers.rb (2)

1-8: LGTM: Module structure and dependencies are well-organized.

The module is correctly namespaced within CypressOnRails::Vcr, and the inclusion of MiddlewareConfig suggests proper use of configuration options. The structure is clean and follows Ruby conventions.


9-11: LGTM: Efficient VCR configuration with memoization.

The vcr method uses memoization to ensure that VCR is configured only once, which is an excellent practice for performance optimization. The use of a private method for configuration keeps the public interface clean and follows the principle of encapsulation.

spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb (3)

1-6: LGTM: File structure and imports are appropriate.

The file structure and imports are well-organized and include all necessary dependencies for the tests. The nested module structure (CypressOnRails::Vcr) is appropriate for the context of this spec file.


7-19: LGTM: Test setup is comprehensive and well-structured.

The test setup provides all necessary mocks and helpers for the tests. The use of let statements for app, vcr, and env allows for easy reuse and modification in individual test cases. The rack_input helper method is a nice touch for simplifying JSON input creation.


1-177: Overall assessment: Well-structured and comprehensive tests with room for minor improvements.

This spec file for InsertEjectMiddleware is well-written and covers a wide range of scenarios for VCR cassette insertion and ejection. The tests are thorough and provide good coverage of both successful operations and error handling.

Key strengths:

  1. Comprehensive test coverage for different VCR options and error cases.
  2. Well-structured setup with appropriate use of RSpec features like let and before.
  3. Clear separation of concerns between insert, eject, and other path tests.

Suggestions for improvement:

  1. Refactor repetitive test structures using shared examples or custom matchers.
  2. Minor adjustments to the "Other paths" tests for better failure reporting.
  3. Address style issues flagged by RuboCop, particularly trailing commas in multiline arrays.

These improvements would enhance the maintainability and readability of the tests without compromising their effectiveness. Overall, this is a solid test suite that provides confidence in the functionality of the InsertEjectMiddleware.

🧰 Tools
🪛 rubocop

[convention] 6-176: Module has too many lines. [138/100]

(Metrics/ModuleLength)


[convention] 31-31: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 43-43: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 54-54: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 65-65: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 76-76: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 89-89: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 100-100: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 111-111: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 125-125: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 138-138: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 148-148: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)

@MUTOgen
Copy link
Author

MUTOgen commented Oct 21, 2024

@justin808 PR itself is ready.
I've been checking tests behavior with this branch on the client's project for a while. My main concern is ensuring it works stable over time on existing or newly added tests.
At the moment, I can't say it works stable. CI fails on a few tests randomly. The number of such "problematic" tests may vary.
I spent some time debugging it locally. One specific test may be successful a few times in a row, it uses a cassette as expected. But after that, there may be a few runs, when this VCR cassette is not used at all (real API calls executed).

@grantspeelman Any ideas on reasons for that?
I can't complain about using this branch #93
I remember your comment here about workers/threads #93 (comment)
I tried changing the max threads and concurrency to 1 on CI, but it still doesn't work perfectly.

@grantspeelman
Copy link
Collaborator

@MUTOgen sorry, nothing comes to mind :(

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b5e5202 and bacf5c5.

📒 Files selected for processing (1)
  • lib/cypress_on_rails/vcr/use_cassette_middleware.rb (1 hunks)

lib/cypress_on_rails/vcr/use_cassette_middleware.rb Outdated Show resolved Hide resolved
@MUTOgen
Copy link
Author

MUTOgen commented Dec 8, 2024

Hey @grantspeelman
I'd like to pop this up again. After investigation, it looks like the source of all the flakiness that I experienced is VCR config overlap.

At the moment, we have 2 places:

I tried to remove the latter and pass project-specific VCR config using gem initializer (new option, like vcr_options = { ... })
As I can see, it started to work much better. So, I'd like to consider this refactoring.

My question is: Is there any reason to have this config in cypress_helper.rb? Do you see any cons to have it under the gem config and remove from cypress_helper.rb?

cypress_on_rails.rb

CypressOnRails.configure do |c|
  ...
  c.use_vcr_use_cassette_middleware = true
  c.vcr_options = {
    # VCR options
    hook_into: :webmock,
    ignore_localhost: true,
    ...
  }
end

@grantspeelman
Copy link
Collaborator

Hey @grantspeelman I'd like to pop this up again. After investigation, it looks like the source of all the flakiness that I experienced is VCR config overlap.

At the moment, we have 2 places:

* VCR config in gem itself https://github.com/shakacode/cypress-on-rails/blob/master/lib/cypress_on_rails/vcr_middleware.rb#L56-L63

* project-level VCR config in helper (from README) https://github.com/shakacode/cypress-on-rails/blob/master/README.md?plain=1#L388-L395

I tried to remove the latter and pass project-specific VCR config using gem initializer (new option, like vcr_options = { ... }) As I can see, it started to work much better. So, I'd like to consider this refactoring.

My question is: Is there any reason to have this config in cypress_helper.rb? Do you see any cons to have it under the gem config and remove from cypress_helper.rb?

cypress_on_rails.rb

CypressOnRails.configure do |c|
  ...
  c.use_vcr_use_cassette_middleware = true
  c.vcr_options = {
    # VCR options
    hook_into: :webmock,
    ignore_localhost: true,
    ...
  }
end

Don't see any issues with this approach 👍🏽

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (13)
lib/generators/cypress_on_rails/templates/spec/cypress/support/commands.js (2)

32-44: Consider enhancing the fetch interceptor's robustness

While the implementation is functional, consider these improvements:

  1. Type checking for the options parameter
  2. Validation of the path parameter
  3. More specific error handling for JSON parsing

Here's a suggested enhancement:

-    const fetch = (path, options, ...rest) => {
+    const fetch = (path, options = {}, ...rest) => {
+      if (!path || typeof path !== 'string') {
+        return originalFetch(path, options, ...rest);
+      }
+
       if (options && options.body) {
         try {
           const body = JSON.parse(options.body);
           if (body.operationName) {
             return originalFetch(`${path}?operation=${body.operationName}`, options, ...rest);
           }
-        } catch (e) {
+        } catch (e) {
+          // Only log parsing errors, not structural ones
+          if (!(e instanceof SyntaxError)) {
+            console.error('GraphQL mock encountered an error:', e);
+          }
           return originalFetch(path, options, ...rest);
         }
       }

28-28: Add comprehensive documentation for the GraphQL mock command

The current comment is too brief. Consider adding documentation that explains:

  1. The purpose and use cases for this command
  2. How it integrates with VCR use_cassette
  3. Examples of usage in tests
  4. Any limitations or gotchas

Here's a suggested documentation block:

-// -- This is for Graphql usage. Add proxy-like mock to add operation name into query string --
+/**
+ * Custom command for GraphQL testing with VCR cassettes
+ * 
+ * This command modifies the window.fetch behavior to include GraphQL operation names
+ * in the request URL, making it easier to match and record specific operations in
+ * VCR cassettes.
+ *
+ * @example
+ * // In your cypress test
+ * beforeEach(() => {
+ *   cy.mockGraphQL();
+ * });
+ *
+ * it('fetches data', () => {
+ *   // Your GraphQL operation will now include ?operation=OperationName in the URL
+ *   cy.request('/graphql', { 
+ *     body: { 
+ *       operationName: 'GetUser',
+ *       query: '...'
+ *     }
+ *   });
+ * });
+ *
+ * @note This should be used in conjunction with VCR use_cassette middleware
+ */
README.md (3)

385-387: Improve list formatting consistency

The unordered list should use consistent markers throughout the document.

-It can be used in two modes:
-- with separate insert/eject calls (more general, recommended way)
-- with use_cassette wrapper (supports only GraphQL integration)
+It can be used in two modes:
+* with separate insert/eject calls (more general, recommended way)
+* with use_cassette wrapper (supports only GraphQL integration)
🧰 Tools
🪛 Markdownlint (0.37.0)

386-386: Expected: asterisk; Actual: dash
Unordered list style

(MD004, ul-style)


387-387: Expected: asterisk; Actual: dash
Unordered list style

(MD004, ul-style)


501-505: Add troubleshooting section for test stability

Given the reported issues with test stability and CI failures, consider adding a troubleshooting section to address common issues.

+### Troubleshooting VCR Integration
+
+#### Test Stability Issues
+
+If you encounter intermittent test failures with VCR:
+
+1. Ensure VCR configuration is not duplicated between the gem and project level
+2. Configure VCR to ignore non-deterministic request headers:
+   ```ruby
+   c.vcr_options = {
+     hook_into: :webmock,
+     default_cassette_options: { 
+       record: :once,
+       match_requests_on: [:method, :host, :path, :query]
+     },
+   }
+   ```
+3. For CI environments, consider using `:once` record mode during development and `:none` in CI
+4. Ensure your server is configured with a single worker and thread when using VCR

Line range hint 423-449: Add best practices section for VCR usage

The example demonstrates basic VCR usage, but it would be helpful to include best practices for managing cassettes.

+### VCR Best Practices
+
+1. **Cassette Organization**:
+   ```js
+   // Group related requests in a single cassette
+   cy.vcr_insert_cassette('user_profile/update', { 
+     record: "new_episodes",
+     match_requests_on: [:method, :host, :path, :query]
+   })
+   ```
+
+2. **Cassette Cleanup**:
+   ```js
+   // Ensure cassettes are always ejected
+   beforeEach(() => {
+     cy.app('clean') // includes VCR.eject_cassette
+   })
+   
+   afterEach(() => {
+     cy.app('clean')
+   })
+   ```
+
+3. **Error Handling**:
+   ```js
+   // Handle VCR errors gracefully
+   Cypress.on('fail', (error, runnable) => {
+     if (error.message.includes('VCR')) {
+       cy.app('clean')
+     }
+     throw error
+   })
+   ```
🧰 Tools
🪛 Markdownlint (0.37.0)

425-425: null
Bare URL used

(MD034, no-bare-urls)

lib/cypress_on_rails/vcr/middleware_helpers.rb (2)

28-34: Consider validating VCR options before applying them.

The apply_vcr_options method should validate options before application to prevent configuration errors.

Consider adding validation:

 def apply_vcr_options(config)
+  return unless configuration.vcr_options.is_a?(Hash)
+
   configuration.vcr_options.each do |option, value|
     next if option.to_sym == :cassette_library_dir
+    unless option.respond_to?(:to_sym)
+      logger.warn "Invalid VCR option type: #{option.class}. Skipping."
+      next
+    end
     apply_vcr_option(config, option, value)
   end
 end

36-46: Add logging for skipped VCR options.

The apply_vcr_option method silently skips options that VCR doesn't support.

Consider adding logging:

 def apply_vcr_option(config, option, value)
-  return unless config.respond_to?(option) || config.respond_to?("#{option}=")
+  unless config.respond_to?(option) || config.respond_to?("#{option}=")
+    logger.warn "Unsupported VCR option: #{option}. Skipping."
+    return
+  end

   if config.respond_to?("#{option}=")
     config.send("#{option}=", value)
   elsif value.is_a?(Array)
     config.send(option, *value)
   else
     config.send(option, value)
   end
 end
lib/cypress_on_rails/configuration.rb (2)

9-9: Add documentation for new VCR configuration options.

The new attributes lack documentation explaining their purpose and expected values.

Add RDoc documentation:

+    # @return [Boolean] Whether to use VCR's use_cassette middleware
     attr_accessor :use_vcr_use_cassette_middleware
     attr_accessor :before_request
     attr_accessor :logger
+    # @return [Hash] Options to pass to VCR.configure
+    # @example
+    #   config.vcr_options = { hook_into: :webmock }
     attr_accessor :vcr_options

Also applies to: 12-12


37-37: Consider type validation for VCR options.

The reset method sets default values but doesn't ensure type safety when values are changed.

Consider adding type validation:

 def reset
   self.api_prefix = ''
   self.install_folder = 'spec/e2e'
   self.use_middleware = true
   self.use_vcr_middleware = false
   self.use_vcr_use_cassette_middleware = false
   self.before_request = -> (request) {}
   self.logger = Logger.new(STDOUT)
   self.vcr_options = {}
 end

+def vcr_options=(options)
+  unless options.nil? || options.is_a?(Hash)
+    logger.warn "vcr_options must be a Hash or nil, got: #{options.class}"
+  end
+  @vcr_options = options
+end

Also applies to: 40-40

lib/cypress_on_rails/vcr/use_cassette_middleware.rb (1)

47-53: Enhance cassette name generation.

The current implementation could be improved to:

  1. Better organize GraphQL cassettes by operation type
  2. Sanitize cassette names for filesystem safety
  3. Handle nested GraphQL operations

Consider this enhancement:

 def fetch_request_cassette(request)
+  name = if request.path.start_with?('/graphql')
+    params = request.params
+    operation = params['operation']
+    operation_type = params['operationName']
+    "graphql/#{operation_type}/#{operation}"
+  else
+    request.path
+  end
+  sanitize_cassette_name(name)
+end
+
+private
+
+def sanitize_cassette_name(name)
+  name.gsub(%r{[^0-9A-Za-z/\-_]}, '_').gsub(%r{/+}, '/')
 end
spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb (3)

20-115: Refactor VCR insert tests using shared examples.

The tests are comprehensive but contain repetitive structures. Consider using shared examples to improve maintainability.

Consider this refactoring:

RSpec.shared_examples "vcr insert request" do |cassette_name, options = {}|
  it "inserts cassette with correct options" do
    env['rack.input'] = rack_input([cassette_name, options])

    aggregate_failures do
      expect(response).to eq([
        201,
        { 'Content-Type' => 'application/json' },
        ['{"message":"OK"}'],
      ])
      expect(vcr).to have_received(:turn_on!)
      expect(vcr).to have_received(:insert_cassette)
        .with(cassette_name, options.transform_keys(&:to_sym))
    end
  end
end

# Usage
it_behaves_like "vcr insert request", "cas1"
it_behaves_like "vcr insert request", "cas1", { "record" => "new_episodes" }
🧰 Tools
🪛 rubocop (1.69.1)

[convention] 31-31: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 43-43: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 54-54: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 65-65: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 76-76: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 89-89: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 100-100: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 111-111: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


116-152: Refactor VCR eject tests using shared examples.

Similar to the insert tests, the eject tests could benefit from shared examples.

Consider this refactoring:

RSpec.shared_examples "vcr eject error" do |error_class, message|
  it "handles #{error_class} with message" do
    allow(vcr).to receive(:eject_cassette).and_raise(error_class.new(message))

    expect(response).to eq([
      500,
      { 'Content-Type' => 'application/json' },
      [{ message: message }.to_json],
    ])
  end
end

# Usage
it_behaves_like "vcr eject error", ArgumentError, "No cassette to eject"
it_behaves_like "vcr eject error", LoadError, "Cannot load VCR"
🧰 Tools
🪛 rubocop (1.69.1)

[convention] 125-125: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 138-138: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 148-148: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


154-174: Improve "Other paths" test organization.

The tests for other paths could be more focused and better organized.

Consider this refactoring:

RSpec.shared_examples "non vcr path" do |path|
  it "handles #{path} correctly" do
    env['PATH_INFO'] = path
    expect(response).to eq([200, {}, ["app did #{path}"]])
    expect(vcr).to have_received(:turn_off!)
  end
end

describe "Other paths" do
  %w[/ /__e2e__/login command /e2e_command].each do |path|
    it_behaves_like "non vcr path", path
  end
end
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bacf5c5 and 99b53a3.

📒 Files selected for processing (16)
  • README.md (3 hunks)
  • lib/cypress_on_rails/configuration.rb (2 hunks)
  • lib/cypress_on_rails/railtie.rb (1 hunks)
  • lib/cypress_on_rails/vcr/insert_eject_middleware.rb (1 hunks)
  • lib/cypress_on_rails/vcr/middleware_helpers.rb (1 hunks)
  • lib/cypress_on_rails/vcr/use_cassette_middleware.rb (1 hunks)
  • lib/cypress_on_rails/vcr_middleware.rb (0 hunks)
  • lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb (1 hunks)
  • lib/generators/cypress_on_rails/templates/spec/cypress/support/commands.js (1 hunks)
  • lib/generators/cypress_on_rails/templates/spec/cypress/support/on-rails.js (1 hunks)
  • spec/cypress_on_rails/configuration_spec.rb (1 hunks)
  • spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb (1 hunks)
  • spec/cypress_on_rails/vcr/use_cassette_middleware_spec.rb (1 hunks)
  • spec/cypress_on_rails/vcr_middleware_spec.rb (0 hunks)
  • specs_e2e/rails_3_2/config/boot.rb (1 hunks)
  • specs_e2e/rails_4_2/Gemfile (1 hunks)
💤 Files with no reviewable changes (2)
  • spec/cypress_on_rails/vcr_middleware_spec.rb
  • lib/cypress_on_rails/vcr_middleware.rb
✅ Files skipped from review due to trivial changes (1)
  • specs_e2e/rails_3_2/config/boot.rb
🚧 Files skipped from review as they are similar to previous changes (6)
  • specs_e2e/rails_4_2/Gemfile
  • lib/generators/cypress_on_rails/templates/spec/cypress/support/on-rails.js
  • spec/cypress_on_rails/vcr/use_cassette_middleware_spec.rb
  • lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb
  • lib/cypress_on_rails/railtie.rb
  • lib/cypress_on_rails/vcr/insert_eject_middleware.rb
🧰 Additional context used
🪛 Markdownlint (0.37.0)
README.md

386-386: Expected: asterisk; Actual: dash
Unordered list style

(MD004, ul-style)


387-387: Expected: asterisk; Actual: dash
Unordered list style

(MD004, ul-style)

🪛 rubocop (1.69.1)
spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb

[convention] 6-176: Module has too many lines. [138/100]

(Metrics/ModuleLength)


[convention] 31-31: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 43-43: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 54-54: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 65-65: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 76-76: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 89-89: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 100-100: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 111-111: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 125-125: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 138-138: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)


[convention] 148-148: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)

🔇 Additional comments (6)
lib/generators/cypress_on_rails/templates/spec/cypress/support/commands.js (1)

29-47: Why is this command commented out?

The implementation looks solid but is entirely commented out. Please clarify if this is intentional and what conditions need to be met before uncommenting it.

Would you like help creating integration tests to verify this functionality works correctly with VCR use_cassette?

lib/cypress_on_rails/vcr/middleware_helpers.rb (1)

13-15: Consider making the cassette subdirectory configurable.

The hardcoded path "fixtures/vcr_cassettes" limits flexibility.

lib/cypress_on_rails/vcr/use_cassette_middleware.rb (4)

14-19: ⚠️ Potential issue

Add error handling and uncomment VCR initialization.

The current implementation lacks error handling and has a commented-out VCR initialization that might be necessary.

Apply this diff:

 def call(env)
   return @app.call(env) if should_not_use_vcr?

-  # initialize_vcr
-  handle_request_with_vcr(env)
+  initialize_vcr
+  handle_request_with_vcr(env)
+rescue StandardError => e
+  [500, { 'Content-Type' => 'application/json' }, [{ message: e.message }.to_json]]
 end

Likely invalid or redundant comment.


27-31: ⚠️ Potential issue

Fix VCR configuration checks.

The current implementation has several issues:

  1. Uses ActiveSupport's present? method which may not be available.
  2. Accesses undefined cassette_library_dir.

Apply this diff:

 def should_not_use_vcr?
   vcr_defined? &&
-    VCR.configuration.cassette_library_dir.present? &&
-    VCR.configuration.cassette_library_dir != cassette_library_dir
+    !VCR.configuration.cassette_library_dir.to_s.empty? &&
+    VCR.configuration.cassette_library_dir != configuration.cassette_library_dir
 end

Likely invalid or redundant comment.


33-45: ⚠️ Potential issue

Fix instance variable references and add logger configuration.

The code has incorrect instance variable references and undefined logger usage.

Apply this diff:

 def initialize_vcr
   WebMock.enable! if defined?(WebMock)
-  vcr.turn_on!
+  @vcr.turn_on!
 end

 def handle_request_with_vcr(env)
   request = Rack::Request.new(env)
   cassette_name = fetch_request_cassette(request)
-  vcr.use_cassette(cassette_name) do
-    logger.info "Handle request with cassette name: #{cassette_name}"
+  @vcr.use_cassette(cassette_name) do
+    configuration.logger&.info "Handle request with cassette name: #{cassette_name}"
     @app.call(env)
   end
 end

Likely invalid or redundant comment.


9-12: ⚠️ Potential issue

Add super call and validate VCR instance.

The initialize method needs to call super to ensure proper parent class initialization. Additionally, consider validating the VCR instance to prevent potential nil errors.

Apply this diff:

 def initialize(app, vcr = nil)
+  super()
   @app = app
+  raise ArgumentError, 'VCR instance is required' if vcr.nil?
   @vcr = vcr
 end

Likely invalid or redundant comment.

README.md Show resolved Hide resolved
README.md Show resolved Hide resolved
spec/cypress_on_rails/configuration_spec.rb Show resolved Hide resolved
@justin808
Copy link
Member

@MUTOgen why are you spending time on Rails 5.2. That's too old.

@MUTOgen
Copy link
Author

MUTOgen commented Dec 14, 2024

@justin808 That's what we use for e2e tests.
Makes sense to update, something like:
Rails 3,4,5 ---> Rails 6,7,8(new one)

Cc @grantspeelman

Copy link

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (3)
lib/cypress_on_rails/vcr/use_cassette_middleware.rb (3)

14-19: Consider thread safety in VCR initialization

The current implementation might face race conditions in multi-threaded environments where multiple requests could attempt to initialize VCR simultaneously.

Consider adding a thread-safe initialization mechanism:

 def call(env)
   return @app.call(env) if should_not_use_vcr?

-  initialize_vcr
+  @vcr_initialized ||= Mutex.new.synchronize { initialize_vcr }
   handle_request_with_vcr(env)
 end

41-44: Add error handling and logging improvements

The current implementation lacks proper error handling and logging context.

Consider this enhancement:

-vcr.use_cassette(cassette_name) do
-  logger.info "Handle request with cassette name: #{cassette_name}"
-  @app.call(env)
+vcr.use_cassette(cassette_name) do
+  logger&.info("VCR: Using cassette '#{cassette_name}' for #{request.request_method} #{request.path}")
+  begin
+    @app.call(env)
+  rescue => e
+    logger&.error("VCR: Error processing request with cassette '#{cassette_name}': #{e.message}")
+    raise
+  end
 end

47-53: Enhance GraphQL cassette naming strategy

The current GraphQL cassette naming could be improved to handle more edge cases and provide better organization.

Consider this enhancement:

 def fetch_request_cassette(request)
-  if request.path.start_with?('/graphql') && request.params.key?('operation')
-    "#{request.path}/#{request.params['operation']}"
+  if request.path.start_with?('/graphql')
+    operation = request.params['operation']
+    variables = request.params['variables']
+    "graphql/#{operation || 'anonymous'}/#{Digest::MD5.hexdigest(variables.to_s)}"
   else
-    request.path
+    request.path.sub(/^\//, '').tr('/', '_')
   end
 end

This improvement:

  1. Handles anonymous GraphQL operations
  2. Includes variables in the cassette name to differentiate between same operations with different variables
  3. Creates more filesystem-friendly cassette names
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4be8aa9 and 5afef6a.

📒 Files selected for processing (1)
  • lib/cypress_on_rails/vcr/use_cassette_middleware.rb (1 hunks)
🔇 Additional comments (2)
lib/cypress_on_rails/vcr/use_cassette_middleware.rb (2)

9-12: Call super in initialize method

The initialize method should call super to ensure proper initialization of the parent class.

Apply this fix:

 def initialize(app, vcr = nil)
+  super()
   @app = app
   @vcr = vcr
 end

27-31: ⚠️ Potential issue

Fix undefined variable and Rails dependency

There are two issues in the should_not_use_vcr? method:

  1. cassette_library_dir is undefined
  2. present? is a Rails-specific method

Apply these fixes:

 def should_not_use_vcr?
   vcr_defined? &&
-    VCR.configuration.cassette_library_dir.present? &&
-    VCR.configuration.cassette_library_dir != cassette_library_dir
+    !VCR.configuration.cassette_library_dir.to_s.empty? &&
+    VCR.configuration.cassette_library_dir != configuration.cassette_library_dir
 end

Likely invalid or redundant comment.

@MUTOgen
Copy link
Author

MUTOgen commented Dec 15, 2024

2 successful runs in a row for a client project 🎉
Looks much better now
Screenshot 2024-12-15 at 20 36 06

I'm gonna keep an eye on it for a few days there 👀
Meanwhile, @grantspeelman could you take a look at a few latest commits? There shouldn't be much to review. Probably, the most interesting one is 99b53a3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants