cypress-on-rails 1.17.0 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/claude-code-review.yml +57 -0
- data/.github/workflows/claude.yml +50 -0
- data/.github/workflows/ruby.yml +14 -14
- data/CHANGELOG.md +319 -98
- data/README.md +271 -23
- data/RELEASING.md +200 -0
- data/Rakefile +1 -4
- data/cypress-on-rails.gemspec +1 -0
- data/docs/BEST_PRACTICES.md +678 -0
- data/docs/DX_IMPROVEMENTS.md +163 -0
- data/docs/PLAYWRIGHT_GUIDE.md +554 -0
- data/docs/RELEASE.md +124 -0
- data/docs/TROUBLESHOOTING.md +351 -0
- data/docs/VCR_GUIDE.md +499 -0
- data/docs/authentication.md +30 -0
- data/docs/factory_bot_associations.md +14 -0
- data/lib/cypress_on_rails/configuration.rb +29 -0
- data/lib/cypress_on_rails/railtie.rb +17 -2
- data/lib/cypress_on_rails/server.rb +197 -0
- data/lib/cypress_on_rails/state_reset_middleware.rb +58 -0
- data/lib/cypress_on_rails/vcr/insert_eject_middleware.rb +75 -0
- data/lib/cypress_on_rails/vcr/middleware_helpers.rb +51 -0
- data/lib/cypress_on_rails/vcr/use_cassette_middleware.rb +56 -0
- data/lib/cypress_on_rails/version.rb +1 -1
- data/lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb +20 -0
- data/lib/generators/cypress_on_rails/templates/spec/cypress/e2e/rails_examples/using_factory_bot.cy.js +2 -2
- data/lib/generators/cypress_on_rails/templates/spec/cypress/e2e/rails_examples/using_scenarios.cy.js +1 -1
- data/lib/generators/cypress_on_rails/templates/spec/cypress/support/commands.js +22 -0
- data/lib/generators/cypress_on_rails/templates/spec/cypress/support/on-rails.js +2 -1
- data/lib/generators/cypress_on_rails/templates/spec/e2e/e2e_helper.rb.erb +0 -5
- data/lib/tasks/cypress.rake +33 -0
- data/rakelib/release.rake +80 -0
- data/rakelib/task_helpers.rb +23 -0
- data/rakelib/update_changelog.rake +63 -0
- data/spec/cypress_on_rails/configuration_spec.rb +4 -1
- data/spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb +177 -0
- data/spec/cypress_on_rails/vcr/use_cassette_middleware_spec.rb +68 -0
- data/specs_e2e/rails_6_1/.gitattributes +10 -0
- data/specs_e2e/rails_6_1/Gemfile +20 -0
- data/specs_e2e/{rails_5_2 → rails_6_1}/Rakefile +1 -1
- data/specs_e2e/rails_6_1/app/assets/stylesheets/application.css +15 -0
- data/specs_e2e/rails_6_1/app/jobs/application_job.rb +7 -0
- data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/layouts/application.html.erb +1 -1
- data/specs_e2e/rails_6_1/bin/bundle +114 -0
- data/specs_e2e/rails_6_1/bin/rails +5 -0
- data/specs_e2e/rails_6_1/bin/rake +5 -0
- data/specs_e2e/{rails_5_2 → rails_6_1}/bin/setup +15 -4
- data/specs_e2e/rails_6_1/bin/spring +14 -0
- data/specs_e2e/rails_6_1/bin/yarn +17 -0
- data/specs_e2e/rails_6_1/config/application.rb +34 -0
- data/specs_e2e/rails_6_1/config/boot.rb +4 -0
- data/specs_e2e/rails_6_1/config/cable.yml +10 -0
- data/specs_e2e/rails_6_1/config/credentials.yml.enc +1 -0
- data/specs_e2e/{rails_5_2 → rails_6_1}/config/database.yml +7 -0
- data/specs_e2e/{rails_5_2 → rails_6_1}/config/environment.rb +1 -1
- data/specs_e2e/{rails_5_2 → rails_6_1}/config/environments/development.rb +22 -5
- data/specs_e2e/rails_6_1/config/environments/production.rb +120 -0
- data/specs_e2e/{rails_5_2 → rails_6_1}/config/environments/test.rb +24 -7
- data/specs_e2e/rails_6_1/config/initializers/backtrace_silencers.rb +8 -0
- data/specs_e2e/{rails_5_2 → rails_6_1}/config/initializers/content_security_policy.rb +5 -0
- data/specs_e2e/{rails_4_2 → rails_6_1}/config/initializers/filter_parameter_logging.rb +3 -1
- data/specs_e2e/rails_6_1/config/initializers/permissions_policy.rb +11 -0
- data/specs_e2e/{rails_3_2 → rails_6_1}/config/initializers/wrap_parameters.rb +5 -1
- data/specs_e2e/{rails_5_2 → rails_6_1}/config/locales/en.yml +1 -1
- data/specs_e2e/rails_6_1/config/master.key +1 -0
- data/specs_e2e/rails_6_1/config/puma.rb +43 -0
- data/specs_e2e/rails_6_1/config/storage.yml +34 -0
- data/specs_e2e/{rails_5_2 → rails_6_1}/config.ru +2 -1
- data/specs_e2e/{rails_5_2 → rails_6_1}/db/migrate/20180621085832_create_posts.rb +1 -1
- data/specs_e2e/rails_6_1/package.json +8 -0
- data/specs_e2e/rails_6_1/playwright-report/index.html +71 -0
- data/specs_e2e/rails_6_1/public/robots.txt +1 -0
- data/specs_e2e/rails_6_1/test-results/.last-run.json +4 -0
- data/specs_e2e/{rails_4_2 → rails_6_1}/test.sh +22 -15
- data/specs_e2e/rails_7_2/.gitattributes +9 -0
- data/specs_e2e/rails_7_2/.gitignore +16 -0
- data/specs_e2e/rails_7_2/.rubocop.yml +8 -0
- data/specs_e2e/rails_7_2/Gemfile +11 -0
- data/specs_e2e/{rails_4_2 → rails_7_2}/Rakefile +1 -1
- data/specs_e2e/rails_7_2/app/assets/stylesheets/application.css +15 -0
- data/specs_e2e/rails_7_2/app/controllers/application_controller.rb +4 -0
- data/specs_e2e/rails_7_2/app/controllers/posts_controller.rb +58 -0
- data/specs_e2e/rails_7_2/app/helpers/posts_helper.rb +2 -0
- data/specs_e2e/rails_7_2/app/jobs/application_job.rb +7 -0
- data/specs_e2e/rails_7_2/app/models/application_record.rb +3 -0
- data/specs_e2e/rails_7_2/app/models/post.rb +2 -0
- data/specs_e2e/rails_7_2/app/views/layouts/application.html.erb +22 -0
- data/specs_e2e/rails_7_2/app/views/posts/_form.html.erb +32 -0
- data/specs_e2e/rails_7_2/app/views/posts/edit.html.erb +6 -0
- data/specs_e2e/rails_7_2/app/views/posts/index.html.erb +31 -0
- data/specs_e2e/rails_7_2/app/views/posts/new.html.erb +5 -0
- data/specs_e2e/rails_7_2/app/views/posts/show.html.erb +19 -0
- data/specs_e2e/rails_7_2/bin/brakeman +7 -0
- data/specs_e2e/rails_7_2/bin/bundle +109 -0
- data/specs_e2e/rails_7_2/bin/importmap +4 -0
- data/specs_e2e/rails_7_2/bin/rails +4 -0
- data/specs_e2e/rails_7_2/bin/rake +4 -0
- data/specs_e2e/rails_7_2/bin/setup +37 -0
- data/specs_e2e/rails_7_2/config/application.rb +37 -0
- data/specs_e2e/rails_7_2/config/boot.rb +4 -0
- data/specs_e2e/rails_7_2/config/cable.yml +10 -0
- data/specs_e2e/rails_7_2/config/credentials.yml.enc +1 -0
- data/specs_e2e/rails_7_2/config/database.yml +32 -0
- data/specs_e2e/{rails_4_2 → rails_7_2}/config/environment.rb +1 -1
- data/specs_e2e/rails_7_2/config/environments/development.rb +54 -0
- data/specs_e2e/rails_7_2/config/environments/production.rb +105 -0
- data/specs_e2e/rails_7_2/config/environments/test.rb +45 -0
- data/specs_e2e/rails_7_2/config/importmap.rb +7 -0
- data/specs_e2e/rails_7_2/config/initializers/content_security_policy.rb +25 -0
- data/specs_e2e/rails_7_2/config/initializers/filter_parameter_logging.rb +8 -0
- data/specs_e2e/{rails_5_2 → rails_7_2}/config/initializers/inflections.rb +4 -4
- data/specs_e2e/rails_7_2/config/initializers/permissions_policy.rb +13 -0
- data/specs_e2e/rails_7_2/config/locales/en.yml +31 -0
- data/specs_e2e/rails_7_2/config/master.key +1 -0
- data/specs_e2e/rails_7_2/config/puma.rb +34 -0
- data/specs_e2e/rails_7_2/config/routes.rb +5 -0
- data/specs_e2e/rails_7_2/config/storage.yml +34 -0
- data/specs_e2e/{rails_4_2 → rails_7_2}/config.ru +3 -1
- data/specs_e2e/rails_7_2/db/migrate/20180621085832_create_posts.rb +11 -0
- data/specs_e2e/rails_7_2/db/seeds.rb +9 -0
- data/specs_e2e/rails_7_2/db/test.sqlite3-shm +0 -0
- data/specs_e2e/rails_7_2/db/test.sqlite3-wal +0 -0
- data/specs_e2e/rails_7_2/package.json +8 -0
- data/specs_e2e/rails_7_2/playwright-report/index.html +71 -0
- data/specs_e2e/{rails_4_2 → rails_7_2}/public/404.html +6 -6
- data/specs_e2e/rails_7_2/public/406-unsupported-browser.html +66 -0
- data/specs_e2e/{rails_4_2 → rails_7_2}/public/422.html +6 -6
- data/specs_e2e/{rails_4_2 → rails_7_2}/public/500.html +6 -6
- data/specs_e2e/rails_7_2/public/icon.png +0 -0
- data/specs_e2e/rails_7_2/public/icon.svg +3 -0
- data/specs_e2e/rails_7_2/public/robots.txt +1 -0
- data/specs_e2e/rails_7_2/storage/test.sqlite3 +0 -0
- data/specs_e2e/rails_7_2/test/controllers/posts_controller_test.rb +48 -0
- data/specs_e2e/rails_7_2/test/cypress_fixtures/posts.yml +11 -0
- data/specs_e2e/rails_7_2/test/fixtures/posts.yml +11 -0
- data/specs_e2e/rails_7_2/test/models/post_test.rb +7 -0
- data/specs_e2e/rails_7_2/test-results/.last-run.json +4 -0
- data/specs_e2e/rails_7_2/test.sh +57 -0
- data/specs_e2e/rails_8/.gitattributes +9 -0
- data/specs_e2e/rails_8/.gitignore +16 -0
- data/specs_e2e/rails_8/.rubocop.yml +8 -0
- data/specs_e2e/rails_8/Gemfile +20 -0
- data/specs_e2e/{rails_3_2 → rails_8}/Rakefile +2 -3
- data/specs_e2e/rails_8/app/assets/stylesheets/application.css +10 -0
- data/specs_e2e/rails_8/app/controllers/application_controller.rb +4 -0
- data/specs_e2e/rails_8/app/controllers/posts_controller.rb +58 -0
- data/specs_e2e/rails_8/app/helpers/posts_helper.rb +2 -0
- data/specs_e2e/rails_8/app/jobs/application_job.rb +7 -0
- data/specs_e2e/rails_8/app/models/application_record.rb +3 -0
- data/specs_e2e/rails_8/app/models/post.rb +2 -0
- data/specs_e2e/rails_8/app/views/layouts/application.html.erb +27 -0
- data/specs_e2e/rails_8/app/views/posts/_form.html.erb +32 -0
- data/specs_e2e/rails_8/app/views/posts/edit.html.erb +6 -0
- data/specs_e2e/rails_8/app/views/posts/index.html.erb +31 -0
- data/specs_e2e/rails_8/app/views/posts/new.html.erb +5 -0
- data/specs_e2e/rails_8/app/views/posts/show.html.erb +19 -0
- data/specs_e2e/rails_8/bin/brakeman +7 -0
- data/specs_e2e/rails_8/bin/bundle +109 -0
- data/specs_e2e/rails_8/bin/dev +2 -0
- data/specs_e2e/rails_8/bin/importmap +4 -0
- data/specs_e2e/rails_8/bin/rails +4 -0
- data/specs_e2e/rails_8/bin/rake +4 -0
- data/specs_e2e/rails_8/bin/setup +34 -0
- data/specs_e2e/rails_8/bin/thrust +5 -0
- data/specs_e2e/rails_8/config/application.rb +27 -0
- data/specs_e2e/rails_8/config/boot.rb +4 -0
- data/specs_e2e/rails_8/config/cable.yml +17 -0
- data/specs_e2e/rails_8/config/cache.yml +16 -0
- data/specs_e2e/rails_8/config/credentials.yml.enc +1 -0
- data/specs_e2e/rails_8/config/database.yml +41 -0
- data/specs_e2e/rails_8/config/deploy.yml +116 -0
- data/specs_e2e/rails_8/config/environment.rb +5 -0
- data/specs_e2e/rails_8/config/environments/development.rb +57 -0
- data/specs_e2e/rails_8/config/environments/production.rb +90 -0
- data/specs_e2e/rails_8/config/environments/test.rb +45 -0
- data/specs_e2e/rails_8/config/importmap.rb +7 -0
- data/specs_e2e/rails_8/config/initializers/content_security_policy.rb +25 -0
- data/specs_e2e/rails_8/config/initializers/filter_parameter_logging.rb +8 -0
- data/specs_e2e/rails_8/config/initializers/inflections.rb +16 -0
- data/specs_e2e/rails_8/config/locales/en.yml +31 -0
- data/specs_e2e/rails_8/config/master.key +1 -0
- data/specs_e2e/rails_8/config/puma.rb +41 -0
- data/specs_e2e/rails_8/config/queue.yml +18 -0
- data/specs_e2e/rails_8/config/recurring.yml +10 -0
- data/specs_e2e/rails_8/config/routes.rb +5 -0
- data/specs_e2e/rails_8/config/storage.yml +34 -0
- data/specs_e2e/rails_8/config.ru +6 -0
- data/specs_e2e/rails_8/db/cable_schema.rb +11 -0
- data/specs_e2e/rails_8/db/cache_schema.rb +14 -0
- data/specs_e2e/rails_8/db/migrate/20180621085832_create_posts.rb +11 -0
- data/specs_e2e/rails_8/db/queue_schema.rb +129 -0
- data/specs_e2e/rails_8/db/seeds.rb +9 -0
- data/specs_e2e/rails_8/package.json +8 -0
- data/specs_e2e/rails_8/playwright-report/index.html +71 -0
- data/specs_e2e/rails_8/public/400.html +114 -0
- data/specs_e2e/rails_8/public/404.html +114 -0
- data/specs_e2e/rails_8/public/406-unsupported-browser.html +114 -0
- data/specs_e2e/rails_8/public/422.html +114 -0
- data/specs_e2e/rails_8/public/500.html +114 -0
- data/specs_e2e/rails_8/public/icon.png +0 -0
- data/specs_e2e/rails_8/public/icon.svg +3 -0
- data/specs_e2e/rails_8/public/robots.txt +1 -0
- data/specs_e2e/rails_8/storage/test.sqlite3 +0 -0
- data/specs_e2e/rails_8/storage/test.sqlite3-shm +0 -0
- data/specs_e2e/rails_8/storage/test.sqlite3-wal +0 -0
- data/specs_e2e/rails_8/test/application_system_test_case.rb +5 -0
- data/specs_e2e/rails_8/test/controllers/posts_controller_test.rb +48 -0
- data/specs_e2e/rails_8/test/cypress_fixtures/posts.yml +11 -0
- data/specs_e2e/rails_8/test/fixtures/posts.yml +11 -0
- data/specs_e2e/rails_8/test/models/post_test.rb +7 -0
- data/specs_e2e/rails_8/test/test_helper.rb +15 -0
- data/specs_e2e/rails_8/test-results/.last-run.json +4 -0
- data/specs_e2e/{rails_5_2 → rails_8}/test.sh +1 -1
- metadata +246 -150
- data/lib/cypress_on_rails/vcr_middleware.rb +0 -73
- data/spec/cypress_on_rails/vcr_middleware_spec.rb +0 -119
- data/specs_e2e/rails_3_2/.gitignore +0 -9
- data/specs_e2e/rails_3_2/.ruby_version +0 -1
- data/specs_e2e/rails_3_2/Gemfile +0 -7
- data/specs_e2e/rails_3_2/README.rdoc +0 -261
- data/specs_e2e/rails_3_2/app/assets/stylesheets/application.css +0 -13
- data/specs_e2e/rails_3_2/app/controllers/application_controller.rb +0 -3
- data/specs_e2e/rails_3_2/app/controllers/welcome_controller.rb +0 -4
- data/specs_e2e/rails_3_2/app/helpers/application_helper.rb +0 -2
- data/specs_e2e/rails_3_2/app/models/post.rb +0 -21
- data/specs_e2e/rails_3_2/app/views/layouts/application.html.erb +0 -13
- data/specs_e2e/rails_3_2/app/views/welcome/index.html.erb +0 -24
- data/specs_e2e/rails_3_2/bin/rails +0 -6
- data/specs_e2e/rails_3_2/config/application.rb +0 -68
- data/specs_e2e/rails_3_2/config/boot.rb +0 -6
- data/specs_e2e/rails_3_2/config/environment.rb +0 -5
- data/specs_e2e/rails_3_2/config/environments/development.rb +0 -31
- data/specs_e2e/rails_3_2/config/environments/production.rb +0 -64
- data/specs_e2e/rails_3_2/config/environments/test.rb +0 -35
- data/specs_e2e/rails_3_2/config/initializers/backtrace_silencers.rb +0 -7
- data/specs_e2e/rails_3_2/config/initializers/inflections.rb +0 -15
- data/specs_e2e/rails_3_2/config/initializers/mime_types.rb +0 -5
- data/specs_e2e/rails_3_2/config/initializers/secret_token.rb +0 -7
- data/specs_e2e/rails_3_2/config/initializers/session_store.rb +0 -8
- data/specs_e2e/rails_3_2/config/locales/en.yml +0 -5
- data/specs_e2e/rails_3_2/config/routes.rb +0 -60
- data/specs_e2e/rails_3_2/config.ru +0 -4
- data/specs_e2e/rails_3_2/public/404.html +0 -26
- data/specs_e2e/rails_3_2/public/422.html +0 -26
- data/specs_e2e/rails_3_2/public/500.html +0 -25
- data/specs_e2e/rails_3_2/public/robots.txt +0 -5
- data/specs_e2e/rails_3_2/test.sh +0 -50
- data/specs_e2e/rails_4_2/.gitignore +0 -12
- data/specs_e2e/rails_4_2/Gemfile +0 -11
- data/specs_e2e/rails_4_2/README.rdoc +0 -28
- data/specs_e2e/rails_4_2/app/assets/javascripts/using_vcr.js +0 -2
- data/specs_e2e/rails_4_2/app/assets/stylesheets/using_vcr.css +0 -4
- data/specs_e2e/rails_4_2/app/controllers/application_controller.rb +0 -5
- data/specs_e2e/rails_4_2/app/controllers/using_vcr_controller.rb +0 -10
- data/specs_e2e/rails_4_2/app/controllers/welcome_controller.rb +0 -4
- data/specs_e2e/rails_4_2/app/models/post.rb +0 -23
- data/specs_e2e/rails_4_2/app/views/layouts/application.html.erb +0 -12
- data/specs_e2e/rails_4_2/app/views/using_vcr/index.html.erb +0 -6
- data/specs_e2e/rails_4_2/app/views/using_vcr/record_cats.html.erb +0 -7
- data/specs_e2e/rails_4_2/app/views/welcome/index.html.erb +0 -24
- data/specs_e2e/rails_4_2/bin/bundle +0 -3
- data/specs_e2e/rails_4_2/bin/rails +0 -4
- data/specs_e2e/rails_4_2/bin/rake +0 -4
- data/specs_e2e/rails_4_2/bin/setup +0 -29
- data/specs_e2e/rails_4_2/config/application.rb +0 -32
- data/specs_e2e/rails_4_2/config/boot.rb +0 -3
- data/specs_e2e/rails_4_2/config/environments/development.rb +0 -25
- data/specs_e2e/rails_4_2/config/environments/production.rb +0 -64
- data/specs_e2e/rails_4_2/config/environments/test.rb +0 -42
- data/specs_e2e/rails_4_2/config/initializers/backtrace_silencers.rb +0 -7
- data/specs_e2e/rails_4_2/config/initializers/cookies_serializer.rb +0 -3
- data/specs_e2e/rails_4_2/config/initializers/session_store.rb +0 -3
- data/specs_e2e/rails_4_2/config/initializers/to_time_preserves_timezone.rb +0 -10
- data/specs_e2e/rails_4_2/config/initializers/wrap_parameters.rb +0 -9
- data/specs_e2e/rails_4_2/config/locales/en.yml +0 -23
- data/specs_e2e/rails_4_2/config/routes.rb +0 -61
- data/specs_e2e/rails_4_2/config/secrets.yml +0 -22
- data/specs_e2e/rails_4_2/package.json +0 -12
- data/specs_e2e/rails_4_2/playwright-report/index.html +0 -62
- data/specs_e2e/rails_4_2/public/favicon.ico +0 -0
- data/specs_e2e/rails_4_2/public/robots.txt +0 -5
- data/specs_e2e/rails_4_2/spec/fixtures/vcr_cassettes/cats.yml +0 -63
- data/specs_e2e/rails_5_2/Gemfile +0 -15
- data/specs_e2e/rails_5_2/app/assets/javascripts/posts.js +0 -2
- data/specs_e2e/rails_5_2/app/assets/stylesheets/posts.css +0 -4
- data/specs_e2e/rails_5_2/app/assets/stylesheets/scaffold.css +0 -80
- data/specs_e2e/rails_5_2/app/jobs/application_job.rb +0 -2
- data/specs_e2e/rails_5_2/app/views/welcome/index.html.erb +0 -5
- data/specs_e2e/rails_5_2/bin/bundle +0 -3
- data/specs_e2e/rails_5_2/bin/rails +0 -4
- data/specs_e2e/rails_5_2/bin/rake +0 -4
- data/specs_e2e/rails_5_2/bin/update +0 -25
- data/specs_e2e/rails_5_2/config/application.rb +0 -33
- data/specs_e2e/rails_5_2/config/boot.rb +0 -4
- data/specs_e2e/rails_5_2/config/credentials.yml.enc +0 -1
- data/specs_e2e/rails_5_2/config/environments/production.rb +0 -68
- data/specs_e2e/rails_5_2/config/initializers/backtrace_silencers.rb +0 -7
- data/specs_e2e/rails_5_2/config/initializers/filter_parameter_logging.rb +0 -4
- data/specs_e2e/rails_5_2/config/initializers/mime_types.rb +0 -4
- data/specs_e2e/rails_5_2/config/initializers/wrap_parameters.rb +0 -9
- data/specs_e2e/rails_5_2/config/master.key +0 -1
- data/specs_e2e/rails_5_2/public/favicon.ico +0 -0
- data/specs_e2e/rails_5_2/public/robots.txt +0 -1
- /data/specs_e2e/{rails_5_2 → rails_6_1}/.gitignore +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/app/controllers/application_controller.rb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/app/controllers/posts_controller.rb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/app/helpers/posts_helper.rb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/app/models/application_record.rb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/app/models/post.rb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/_form.html.erb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/edit.html.erb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/index.html.erb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/new.html.erb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/show.html.erb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/config/initializers/application_controller_renderer.rb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/config/initializers/cookies_serializer.rb +0 -0
- /data/specs_e2e/{rails_4_2 → rails_6_1}/config/initializers/inflections.rb +0 -0
- /data/specs_e2e/{rails_4_2 → rails_6_1}/config/initializers/mime_types.rb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/config/routes.rb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/public/404.html +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/public/422.html +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/public/500.html +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/public/apple-touch-icon-precomposed.png +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/public/apple-touch-icon.png +0 -0
- /data/specs_e2e/{rails_3_2 → rails_6_1}/public/favicon.ico +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/test/controllers/posts_controller_test.rb +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/test/cypress_fixtures/posts.yml +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/test/fixtures/posts.yml +0 -0
- /data/specs_e2e/{rails_5_2 → rails_6_1}/test/models/post_test.rb +0 -0
- /data/specs_e2e/{rails_3_2/log → rails_6_1/vendor}/.keep +0 -0
- /data/specs_e2e/{rails_3_2/tmp → rails_7_2/vendor}/.keep +0 -0
- /data/specs_e2e/{rails_4_2/spec → rails_7_2/vendor/javascript}/.keep +0 -0
- /data/specs_e2e/{rails_5_2 → rails_8}/README.md +0 -0
- /data/specs_e2e/{rails_4_2/vendor → rails_8/storage}/.keep +0 -0
- /data/specs_e2e/{rails_5_2 → rails_8}/vendor/.keep +0 -0
- /data/specs_e2e/{rails_3_2/vendor/.gitkeep → rails_8/vendor/javascript/.keep} +0 -0
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'timeout'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'cypress_on_rails/configuration'
|
5
|
+
|
6
|
+
module CypressOnRails
|
7
|
+
class Server
|
8
|
+
attr_reader :host, :port, :framework, :install_folder
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
config = CypressOnRails.configuration
|
12
|
+
|
13
|
+
@framework = options[:framework] || :cypress
|
14
|
+
@host = options[:host] || config.server_host
|
15
|
+
@port = options[:port] || config.server_port || find_available_port
|
16
|
+
@port = @port.to_i if @port
|
17
|
+
@install_folder = options[:install_folder] || config.install_folder || detect_install_folder
|
18
|
+
@transactional = options.fetch(:transactional, config.transactional_server)
|
19
|
+
end
|
20
|
+
|
21
|
+
def open
|
22
|
+
start_server do
|
23
|
+
run_command(open_command, "Opening #{framework} test runner")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def run
|
28
|
+
start_server do
|
29
|
+
result = run_command(run_command_args, "Running #{framework} tests")
|
30
|
+
exit(result ? 0 : 1)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def init
|
35
|
+
ensure_install_folder_exists
|
36
|
+
puts "#{framework.to_s.capitalize} configuration initialized at #{install_folder}"
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def detect_install_folder
|
42
|
+
# Check common locations for cypress/playwright installation
|
43
|
+
possible_folders = ['e2e', 'spec/e2e', 'spec/cypress', 'spec/playwright', 'cypress', 'playwright']
|
44
|
+
folder = possible_folders.find { |f| File.exist?(File.expand_path(f)) }
|
45
|
+
folder || 'e2e'
|
46
|
+
end
|
47
|
+
|
48
|
+
def ensure_install_folder_exists
|
49
|
+
unless File.exist?(install_folder)
|
50
|
+
puts "Creating #{install_folder} directory..."
|
51
|
+
FileUtils.mkdir_p(install_folder)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def find_available_port
|
56
|
+
server = TCPServer.new('127.0.0.1', 0)
|
57
|
+
port = server.addr[1]
|
58
|
+
server.close
|
59
|
+
port
|
60
|
+
end
|
61
|
+
|
62
|
+
def start_server(&block)
|
63
|
+
config = CypressOnRails.configuration
|
64
|
+
|
65
|
+
run_hook(config.before_server_start)
|
66
|
+
|
67
|
+
ENV['CYPRESS'] = '1'
|
68
|
+
ENV['RAILS_ENV'] = 'test'
|
69
|
+
|
70
|
+
server_pid = spawn_server
|
71
|
+
|
72
|
+
begin
|
73
|
+
wait_for_server
|
74
|
+
run_hook(config.after_server_start)
|
75
|
+
|
76
|
+
puts "Rails server started on #{base_url}"
|
77
|
+
|
78
|
+
if @transactional && defined?(ActiveRecord::Base)
|
79
|
+
ActiveRecord::Base.connection.begin_transaction(joinable: false)
|
80
|
+
run_hook(config.after_transaction_start)
|
81
|
+
end
|
82
|
+
|
83
|
+
yield
|
84
|
+
|
85
|
+
ensure
|
86
|
+
run_hook(config.before_server_stop)
|
87
|
+
|
88
|
+
if @transactional && defined?(ActiveRecord::Base)
|
89
|
+
ActiveRecord::Base.connection.rollback_transaction if ActiveRecord::Base.connection.transaction_open?
|
90
|
+
end
|
91
|
+
|
92
|
+
stop_server(server_pid)
|
93
|
+
ENV.delete('CYPRESS')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def spawn_server
|
98
|
+
rails_args = if File.exist?('bin/rails')
|
99
|
+
['bin/rails']
|
100
|
+
else
|
101
|
+
['bundle', 'exec', 'rails']
|
102
|
+
end
|
103
|
+
|
104
|
+
server_args = rails_args + ['server', '-p', port.to_s, '-b', host]
|
105
|
+
|
106
|
+
puts "Starting Rails server: #{server_args.join(' ')}"
|
107
|
+
|
108
|
+
spawn(*server_args, out: $stdout, err: $stderr)
|
109
|
+
end
|
110
|
+
|
111
|
+
def wait_for_server(timeout = 30)
|
112
|
+
Timeout.timeout(timeout) do
|
113
|
+
loop do
|
114
|
+
begin
|
115
|
+
TCPSocket.new(host, port).close
|
116
|
+
break
|
117
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
118
|
+
sleep 0.1
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
rescue Timeout::Error
|
123
|
+
raise "Rails server failed to start on #{host}:#{port} after #{timeout} seconds"
|
124
|
+
end
|
125
|
+
|
126
|
+
def stop_server(pid)
|
127
|
+
if pid
|
128
|
+
puts "Stopping Rails server (PID: #{pid})"
|
129
|
+
Process.kill('TERM', pid)
|
130
|
+
Process.wait(pid)
|
131
|
+
end
|
132
|
+
rescue Errno::ESRCH
|
133
|
+
# Process already terminated
|
134
|
+
end
|
135
|
+
|
136
|
+
def base_url
|
137
|
+
"http://#{host}:#{port}"
|
138
|
+
end
|
139
|
+
|
140
|
+
def open_command
|
141
|
+
case framework
|
142
|
+
when :cypress
|
143
|
+
if command_exists?('yarn')
|
144
|
+
['yarn', 'cypress', 'open', '--project', install_folder, '--config', "baseUrl=#{base_url}"]
|
145
|
+
elsif command_exists?('npx')
|
146
|
+
['npx', 'cypress', 'open', '--project', install_folder, '--config', "baseUrl=#{base_url}"]
|
147
|
+
else
|
148
|
+
['cypress', 'open', '--project', install_folder, '--config', "baseUrl=#{base_url}"]
|
149
|
+
end
|
150
|
+
when :playwright
|
151
|
+
if command_exists?('yarn')
|
152
|
+
['yarn', 'playwright', 'test', '--ui']
|
153
|
+
elsif command_exists?('npx')
|
154
|
+
['npx', 'playwright', 'test', '--ui']
|
155
|
+
else
|
156
|
+
['playwright', 'test', '--ui']
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def run_command_args
|
162
|
+
case framework
|
163
|
+
when :cypress
|
164
|
+
if command_exists?('yarn')
|
165
|
+
['yarn', 'cypress', 'run', '--project', install_folder, '--config', "baseUrl=#{base_url}"]
|
166
|
+
elsif command_exists?('npx')
|
167
|
+
['npx', 'cypress', 'run', '--project', install_folder, '--config', "baseUrl=#{base_url}"]
|
168
|
+
else
|
169
|
+
['cypress', 'run', '--project', install_folder, '--config', "baseUrl=#{base_url}"]
|
170
|
+
end
|
171
|
+
when :playwright
|
172
|
+
if command_exists?('yarn')
|
173
|
+
['yarn', 'playwright', 'test']
|
174
|
+
elsif command_exists?('npx')
|
175
|
+
['npx', 'playwright', 'test']
|
176
|
+
else
|
177
|
+
['playwright', 'test']
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def run_command(command_args, description)
|
183
|
+
puts "#{description}: #{command_args.join(' ')}"
|
184
|
+
system(*command_args)
|
185
|
+
end
|
186
|
+
|
187
|
+
def command_exists?(command)
|
188
|
+
system("which #{command} > /dev/null 2>&1")
|
189
|
+
end
|
190
|
+
|
191
|
+
def run_hook(hook)
|
192
|
+
if hook && hook.respond_to?(:call)
|
193
|
+
hook.call
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module CypressOnRails
|
2
|
+
class StateResetMiddleware
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
if env['PATH_INFO'] == '/__cypress__/reset_state' || env['PATH_INFO'] == '/cypress_rails_reset_state'
|
9
|
+
reset_application_state
|
10
|
+
[200, { 'Content-Type' => 'text/plain' }, ['State reset completed']]
|
11
|
+
else
|
12
|
+
@app.call(env)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def reset_application_state
|
19
|
+
config = CypressOnRails.configuration
|
20
|
+
|
21
|
+
# Default state reset actions
|
22
|
+
if defined?(DatabaseCleaner)
|
23
|
+
DatabaseCleaner.clean_with(:truncation)
|
24
|
+
elsif defined?(ActiveRecord::Base)
|
25
|
+
connection = ActiveRecord::Base.connection
|
26
|
+
|
27
|
+
# Use disable_referential_integrity if available for safer table clearing
|
28
|
+
if connection.respond_to?(:disable_referential_integrity)
|
29
|
+
connection.disable_referential_integrity do
|
30
|
+
connection.tables.each do |table|
|
31
|
+
next if table == 'schema_migrations' || table == 'ar_internal_metadata'
|
32
|
+
connection.execute("DELETE FROM #{connection.quote_table_name(table)}")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
else
|
36
|
+
# Fallback to regular deletion with proper table name quoting
|
37
|
+
connection.tables.each do |table|
|
38
|
+
next if table == 'schema_migrations' || table == 'ar_internal_metadata'
|
39
|
+
connection.execute("DELETE FROM #{connection.quote_table_name(table)}")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Clear Rails cache
|
45
|
+
Rails.cache.clear if defined?(Rails) && Rails.cache
|
46
|
+
|
47
|
+
# Reset any class-level state
|
48
|
+
ActiveSupport::Dependencies.clear if defined?(ActiveSupport::Dependencies)
|
49
|
+
|
50
|
+
# Run after_state_reset hook after cleanup is complete
|
51
|
+
run_hook(config.after_state_reset)
|
52
|
+
end
|
53
|
+
|
54
|
+
def run_hook(hook)
|
55
|
+
hook.call if hook && hook.respond_to?(:call)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative 'middleware_helpers'
|
2
|
+
|
3
|
+
module CypressOnRails
|
4
|
+
module Vcr
|
5
|
+
# Middleware to handle vcr with insert/eject endpoints
|
6
|
+
class InsertEjectMiddleware
|
7
|
+
include MiddlewareHelpers
|
8
|
+
|
9
|
+
def initialize(app, vcr = nil)
|
10
|
+
@app = app
|
11
|
+
@vcr = vcr
|
12
|
+
@first_call = false
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
request = Rack::Request.new(env)
|
17
|
+
if request.path.start_with?('/__e2e__/vcr/insert')
|
18
|
+
configuration.tagged_logged { handle_insert(request) }
|
19
|
+
elsif request.path.start_with?('/__e2e__/vcr/eject')
|
20
|
+
configuration.tagged_logged { handle_eject }
|
21
|
+
else
|
22
|
+
do_first_call unless @first_call
|
23
|
+
@app.call(env)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def handle_insert(req)
|
30
|
+
WebMock.enable! if defined?(WebMock)
|
31
|
+
vcr.turn_on!
|
32
|
+
body = parse_request_body(req)
|
33
|
+
logger.info "vcr insert cassette: #{body}"
|
34
|
+
cassette_name, options = extract_cassette_info(body)
|
35
|
+
vcr.insert_cassette(cassette_name, options)
|
36
|
+
[201, { 'Content-Type' => 'application/json' }, [{ 'message': 'OK' }.to_json]]
|
37
|
+
rescue JSON::ParserError => e
|
38
|
+
[400, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]]
|
39
|
+
rescue LoadError, ArgumentError => e
|
40
|
+
[500, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]]
|
41
|
+
end
|
42
|
+
|
43
|
+
def parse_request_body(req)
|
44
|
+
JSON.parse(req.body.read)
|
45
|
+
end
|
46
|
+
|
47
|
+
def extract_cassette_info(body)
|
48
|
+
cassette_name = body[0]
|
49
|
+
options = (body[1] || {}).symbolize_keys
|
50
|
+
options[:record] = options[:record].to_sym if options[:record]
|
51
|
+
options[:match_requests_on] = options[:match_requests_on].map(&:to_sym) if options[:match_requests_on]
|
52
|
+
options[:serialize_with] = options[:serialize_with].to_sym if options[:serialize_with]
|
53
|
+
options[:persist_with] = options[:persist_with].to_sym if options[:persist_with]
|
54
|
+
[cassette_name, options]
|
55
|
+
end
|
56
|
+
|
57
|
+
def handle_eject
|
58
|
+
logger.info 'vcr eject cassette'
|
59
|
+
vcr.eject_cassette
|
60
|
+
do_first_call
|
61
|
+
[201, { 'Content-Type' => 'application/json' }, [{ 'message': 'OK' }.to_json]]
|
62
|
+
rescue LoadError, ArgumentError => e
|
63
|
+
[500, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]]
|
64
|
+
end
|
65
|
+
|
66
|
+
def do_first_call
|
67
|
+
@first_call = true
|
68
|
+
vcr.turn_off!
|
69
|
+
WebMock.disable! if defined?(WebMock)
|
70
|
+
rescue LoadError
|
71
|
+
# nop
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'cypress_on_rails/middleware_config'
|
2
|
+
|
3
|
+
module CypressOnRails
|
4
|
+
module Vcr
|
5
|
+
# Provides helper methods for VCR middlewares
|
6
|
+
module MiddlewareHelpers
|
7
|
+
include MiddlewareConfig
|
8
|
+
|
9
|
+
def vcr
|
10
|
+
@vcr ||= configure_vcr
|
11
|
+
end
|
12
|
+
|
13
|
+
def cassette_library_dir
|
14
|
+
configuration.vcr_options&.fetch(:cassette_library_dir) do
|
15
|
+
"#{configuration.install_folder}/fixtures/vcr_cassettes"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def configure_vcr
|
22
|
+
require 'vcr'
|
23
|
+
VCR.configure do |config|
|
24
|
+
config.cassette_library_dir = cassette_library_dir
|
25
|
+
apply_vcr_options(config) if configuration.vcr_options.present?
|
26
|
+
end
|
27
|
+
VCR
|
28
|
+
end
|
29
|
+
|
30
|
+
def apply_vcr_options(config)
|
31
|
+
configuration.vcr_options.each do |option, value|
|
32
|
+
next if option.to_sym == :cassette_library_dir
|
33
|
+
|
34
|
+
apply_vcr_option(config, option, value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def apply_vcr_option(config, option, value)
|
39
|
+
return unless config.respond_to?(option) || config.respond_to?("#{option}=")
|
40
|
+
|
41
|
+
if config.respond_to?("#{option}=")
|
42
|
+
config.send("#{option}=", value)
|
43
|
+
elsif value.is_a?(Array)
|
44
|
+
config.send(option, *value)
|
45
|
+
else
|
46
|
+
config.send(option, value)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative 'middleware_helpers'
|
2
|
+
|
3
|
+
module CypressOnRails
|
4
|
+
module Vcr
|
5
|
+
# Middleware to handle vcr with use_cassette
|
6
|
+
class UseCassetteMiddleware
|
7
|
+
include MiddlewareHelpers
|
8
|
+
|
9
|
+
def initialize(app, vcr = nil)
|
10
|
+
@app = app
|
11
|
+
@vcr = vcr
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
return @app.call(env) if should_not_use_vcr?
|
16
|
+
|
17
|
+
initialize_vcr
|
18
|
+
handle_request_with_vcr(env)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def vcr_defined?
|
24
|
+
defined?(VCR) != nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def should_not_use_vcr?
|
28
|
+
vcr_defined? &&
|
29
|
+
VCR.configuration.cassette_library_dir.present? &&
|
30
|
+
VCR.configuration.cassette_library_dir != cassette_library_dir
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize_vcr
|
34
|
+
WebMock.enable! if defined?(WebMock)
|
35
|
+
vcr.turn_on!
|
36
|
+
end
|
37
|
+
|
38
|
+
def handle_request_with_vcr(env)
|
39
|
+
request = Rack::Request.new(env)
|
40
|
+
cassette_name = fetch_request_cassette(request)
|
41
|
+
vcr.use_cassette(cassette_name) do
|
42
|
+
logger.info "Handle request with cassette name: #{cassette_name}"
|
43
|
+
@app.call(env)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def fetch_request_cassette(request)
|
48
|
+
if request.path.start_with?('/graphql') && request.params.key?('operation')
|
49
|
+
"#{request.path}/#{request.params['operation']}"
|
50
|
+
else
|
51
|
+
request.path
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -6,7 +6,27 @@ if defined?(CypressOnRails)
|
|
6
6
|
# please use with extra caution if enabling on hosted servers or starting your local server on 0.0.0.0
|
7
7
|
c.use_middleware = !Rails.env.production?
|
8
8
|
<% unless options.experimental %># <% end %> c.use_vcr_middleware = !Rails.env.production?
|
9
|
+
<% unless options.experimental %># <% end %> # Use this if you want to use use_cassette wrapper instead of manual insert/eject
|
10
|
+
<% unless options.experimental %># <% end %> # c.use_vcr_use_cassette_middleware = !Rails.env.production?
|
11
|
+
<% unless options.experimental %># <% end %> # Pass custom VCR options
|
12
|
+
<% unless options.experimental %># <% end %> c.vcr_options = {
|
13
|
+
<% unless options.experimental %># <% end %> hook_into: :webmock,
|
14
|
+
<% unless options.experimental %># <% end %> default_cassette_options: { record: :once },
|
15
|
+
<% unless options.experimental %># <% end %> cassette_library_dir: File.expand_path("#{__dir__}/../../<%= options.install_folder %>/<%= options.framework %>/fixtures/vcr_cassettes")
|
16
|
+
<% unless options.experimental %># <% end %> }
|
9
17
|
c.logger = Rails.logger
|
18
|
+
|
19
|
+
# Server configuration for rake tasks (cypress:open, cypress:run, playwright:open, playwright:run)
|
20
|
+
# c.server_host = 'localhost' # or use ENV['CYPRESS_RAILS_HOST']
|
21
|
+
# c.server_port = 3001 # or use ENV['CYPRESS_RAILS_PORT']
|
22
|
+
# c.transactional_server = true # Enable automatic transaction rollback between tests
|
23
|
+
|
24
|
+
# Server lifecycle hooks for rake tasks
|
25
|
+
# c.before_server_start = -> { DatabaseCleaner.clean_with(:truncation) }
|
26
|
+
# c.after_server_start = -> { puts "Test server started on port #{CypressOnRails.configuration.server_port}" }
|
27
|
+
# c.after_transaction_start = -> { Rails.application.load_seed }
|
28
|
+
# c.after_state_reset = -> { Rails.cache.clear }
|
29
|
+
# c.before_server_stop = -> { puts "Stopping test server..." }
|
10
30
|
|
11
31
|
# If you want to enable a before_request logic, such as authentication, logging, sending metrics, etc.
|
12
32
|
# Refer to https://www.rubydoc.info/gems/rack/Rack/Request for the `request` argument.
|
@@ -9,7 +9,7 @@ describe('Rails using factory bot examples', function() {
|
|
9
9
|
])
|
10
10
|
cy.visit('/')
|
11
11
|
cy.get('table').find('tbody').should(($tbody) => {
|
12
|
-
// clean should
|
12
|
+
// clean should have removed these from other tests
|
13
13
|
expect($tbody).not.to.contain('Hello World')
|
14
14
|
|
15
15
|
expect($tbody).to.contain('Good bye Mars')
|
@@ -23,7 +23,7 @@ describe('Rails using factory bot examples', function() {
|
|
23
23
|
])
|
24
24
|
cy.visit('/')
|
25
25
|
cy.get('table').find('tbody').should(($tbody) => {
|
26
|
-
// clean should
|
26
|
+
// clean should have removed these from other tests
|
27
27
|
expect($tbody).to.contain('Hello World')
|
28
28
|
expect($tbody).not.to.contain('Good bye Mars')
|
29
29
|
})
|
data/lib/generators/cypress_on_rails/templates/spec/cypress/e2e/rails_examples/using_scenarios.cy.js
CHANGED
@@ -7,7 +7,7 @@ describe('Rails using scenarios examples', function() {
|
|
7
7
|
cy.appScenario('basic')
|
8
8
|
cy.visit('/')
|
9
9
|
cy.get('table').find('tbody').should(($tbody) => {
|
10
|
-
// clean should
|
10
|
+
// clean should have removed these from other tests
|
11
11
|
expect($tbody).not.to.contain('Good bye Mars')
|
12
12
|
expect($tbody).not.to.contain('Hello World')
|
13
13
|
|
@@ -23,3 +23,25 @@
|
|
23
23
|
//
|
24
24
|
// -- This is will overwrite an existing command --
|
25
25
|
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
26
|
+
//
|
27
|
+
//
|
28
|
+
// -- This is for Graphql usage. Add proxy-like mock to add operation name into query string --
|
29
|
+
// Cypress.Commands.add('mockGraphQL', () => {
|
30
|
+
// cy.on('window:before:load', (win) => {
|
31
|
+
// const originalFetch = win.fetch;
|
32
|
+
// const fetch = (path, options, ...rest) => {
|
33
|
+
// if (options && options.body) {
|
34
|
+
// try {
|
35
|
+
// const body = JSON.parse(options.body);
|
36
|
+
// if (body.operationName) {
|
37
|
+
// return originalFetch(`${path}?operation=${body.operationName}`, options, ...rest);
|
38
|
+
// }
|
39
|
+
// } catch (e) {
|
40
|
+
// return originalFetch(path, options, ...rest);
|
41
|
+
// }
|
42
|
+
// }
|
43
|
+
// return originalFetch(path, options, ...rest);
|
44
|
+
// };
|
45
|
+
// cy.stub(win, 'fetch', fetch);
|
46
|
+
// });
|
47
|
+
// });
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// CypressOnRails:
|
1
|
+
// CypressOnRails: don't remove these commands
|
2
2
|
Cypress.Commands.add('appCommands', function (body) {
|
3
3
|
Object.keys(body).forEach(key => body[key] === undefined ? delete body[key] : {});
|
4
4
|
const log = Cypress.log({ name: "APP", message: body, autoEnd: false })
|
@@ -47,6 +47,7 @@ Cypress.Commands.add('appFixtures', function (options) {
|
|
47
47
|
// The next is optional
|
48
48
|
// beforeEach(() => {
|
49
49
|
// cy.app('clean') // have a look at cypress/app_commands/clean.rb
|
50
|
+
// cy.mockGraphQL() // for GraphQL usage with use_cassette, see cypress/support/commands.rb
|
50
51
|
// });
|
51
52
|
|
52
53
|
// comment this out if you do not want to attempt to log additional info on test fail
|
@@ -36,8 +36,3 @@ CypressOnRails::SmartFactoryWrapper.configure(
|
|
36
36
|
Rails.root.join('spec', 'factories', '**', '*.rb')
|
37
37
|
]
|
38
38
|
)
|
39
|
-
|
40
|
-
<% unless options.experimental %># <% end %>require 'vcr'
|
41
|
-
<% unless options.experimental %># <% end %>VCR.configure do |config|
|
42
|
-
<% unless options.experimental %># <% end %> config.hook_into :webmock
|
43
|
-
<% unless options.experimental %># <% end %>end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
namespace :cypress do
|
2
|
+
desc "Open Cypress test runner UI"
|
3
|
+
task :open => :environment do
|
4
|
+
require 'cypress_on_rails/server'
|
5
|
+
CypressOnRails::Server.new.open
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "Run Cypress tests in headless mode"
|
9
|
+
task :run => :environment do
|
10
|
+
require 'cypress_on_rails/server'
|
11
|
+
CypressOnRails::Server.new.run
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Initialize Cypress configuration"
|
15
|
+
task :init => :environment do
|
16
|
+
require 'cypress_on_rails/server'
|
17
|
+
CypressOnRails::Server.new.init
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
namespace :playwright do
|
22
|
+
desc "Open Playwright test runner UI"
|
23
|
+
task :open => :environment do
|
24
|
+
require 'cypress_on_rails/server'
|
25
|
+
CypressOnRails::Server.new(framework: :playwright).open
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Run Playwright tests in headless mode"
|
29
|
+
task :run => :environment do
|
30
|
+
require 'cypress_on_rails/server'
|
31
|
+
CypressOnRails::Server.new(framework: :playwright).run
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler"
|
4
|
+
require_relative "task_helpers"
|
5
|
+
|
6
|
+
class RaisingMessageHandler
|
7
|
+
def add_error(error)
|
8
|
+
raise error
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# rubocop:disable Metrics/BlockLength
|
13
|
+
|
14
|
+
desc("Releases the gem using the given version.
|
15
|
+
|
16
|
+
IMPORTANT: the gem version must be in valid rubygem format (no dashes).
|
17
|
+
|
18
|
+
This task depends on the gem-release (ruby gem) which is installed via `bundle install`
|
19
|
+
|
20
|
+
1st argument: The new version in rubygem format (no dashes). Pass no argument to
|
21
|
+
automatically perform a patch version bump.
|
22
|
+
2nd argument: Perform a dry run by passing 'true' as a second argument.
|
23
|
+
|
24
|
+
Note, accept defaults for rubygems options. Script will pause to get 2FA tokens.
|
25
|
+
|
26
|
+
Example: `rake release[2.1.0,false]`")
|
27
|
+
task :release, %i[gem_version dry_run] do |_t, args|
|
28
|
+
include CypressOnRails::TaskHelpers
|
29
|
+
|
30
|
+
# Check if there are uncommitted changes
|
31
|
+
unless `git status --porcelain`.strip.empty?
|
32
|
+
raise "You have uncommitted changes. Please commit or stash them before releasing."
|
33
|
+
end
|
34
|
+
|
35
|
+
args_hash = args.to_hash
|
36
|
+
|
37
|
+
is_dry_run = args_hash[:dry_run] == 'true'
|
38
|
+
|
39
|
+
gem_version = args_hash.fetch(:gem_version, "")
|
40
|
+
|
41
|
+
# See https://github.com/svenfuchs/gem-release
|
42
|
+
sh_in_dir(gem_root, "git pull --rebase")
|
43
|
+
sh_in_dir(gem_root, "gem bump --no-commit --file lib/cypress_on_rails/version.rb #{gem_version.strip.empty? ? '' : %(--version #{gem_version})}")
|
44
|
+
|
45
|
+
# Read the actual version from the file after bump
|
46
|
+
load File.expand_path("../lib/cypress_on_rails/version.rb", __dir__)
|
47
|
+
actual_version = CypressOnRails::VERSION
|
48
|
+
|
49
|
+
# Update Gemfile.lock files
|
50
|
+
sh_in_dir(gem_root, "bundle install")
|
51
|
+
|
52
|
+
unless is_dry_run
|
53
|
+
# Commit the version bump
|
54
|
+
sh_in_dir(gem_root, "git add lib/cypress_on_rails/version.rb")
|
55
|
+
sh_in_dir(gem_root, "git commit -m \"Release v#{actual_version}\"")
|
56
|
+
|
57
|
+
# Tag the release
|
58
|
+
sh_in_dir(gem_root, "git tag v#{actual_version}")
|
59
|
+
|
60
|
+
# Push the commit and tag
|
61
|
+
sh_in_dir(gem_root, "git push && git push --tags")
|
62
|
+
|
63
|
+
# Release the new gem version
|
64
|
+
puts "Carefully add your OTP for Rubygems. If you get an error, run 'gem release' again."
|
65
|
+
sh_in_dir(gem_root, "gem release")
|
66
|
+
else
|
67
|
+
puts "DRY RUN: Would have committed, tagged v#{actual_version}, pushed, and released gem"
|
68
|
+
end
|
69
|
+
|
70
|
+
msg = <<~MSG
|
71
|
+
Once you have successfully published, run these commands to update CHANGELOG.md:
|
72
|
+
|
73
|
+
bundle exec rake update_changelog
|
74
|
+
git commit -a -m 'Update CHANGELOG.md'
|
75
|
+
git push
|
76
|
+
MSG
|
77
|
+
puts msg
|
78
|
+
end
|
79
|
+
|
80
|
+
# rubocop:enable Metrics/BlockLength
|