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.
Files changed (337) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/claude-code-review.yml +57 -0
  3. data/.github/workflows/claude.yml +50 -0
  4. data/.github/workflows/ruby.yml +14 -14
  5. data/CHANGELOG.md +319 -98
  6. data/README.md +271 -23
  7. data/RELEASING.md +200 -0
  8. data/Rakefile +1 -4
  9. data/cypress-on-rails.gemspec +1 -0
  10. data/docs/BEST_PRACTICES.md +678 -0
  11. data/docs/DX_IMPROVEMENTS.md +163 -0
  12. data/docs/PLAYWRIGHT_GUIDE.md +554 -0
  13. data/docs/RELEASE.md +124 -0
  14. data/docs/TROUBLESHOOTING.md +351 -0
  15. data/docs/VCR_GUIDE.md +499 -0
  16. data/docs/authentication.md +30 -0
  17. data/docs/factory_bot_associations.md +14 -0
  18. data/lib/cypress_on_rails/configuration.rb +29 -0
  19. data/lib/cypress_on_rails/railtie.rb +17 -2
  20. data/lib/cypress_on_rails/server.rb +197 -0
  21. data/lib/cypress_on_rails/state_reset_middleware.rb +58 -0
  22. data/lib/cypress_on_rails/vcr/insert_eject_middleware.rb +75 -0
  23. data/lib/cypress_on_rails/vcr/middleware_helpers.rb +51 -0
  24. data/lib/cypress_on_rails/vcr/use_cassette_middleware.rb +56 -0
  25. data/lib/cypress_on_rails/version.rb +1 -1
  26. data/lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb +20 -0
  27. data/lib/generators/cypress_on_rails/templates/spec/cypress/e2e/rails_examples/using_factory_bot.cy.js +2 -2
  28. data/lib/generators/cypress_on_rails/templates/spec/cypress/e2e/rails_examples/using_scenarios.cy.js +1 -1
  29. data/lib/generators/cypress_on_rails/templates/spec/cypress/support/commands.js +22 -0
  30. data/lib/generators/cypress_on_rails/templates/spec/cypress/support/on-rails.js +2 -1
  31. data/lib/generators/cypress_on_rails/templates/spec/e2e/e2e_helper.rb.erb +0 -5
  32. data/lib/tasks/cypress.rake +33 -0
  33. data/rakelib/release.rake +80 -0
  34. data/rakelib/task_helpers.rb +23 -0
  35. data/rakelib/update_changelog.rake +63 -0
  36. data/spec/cypress_on_rails/configuration_spec.rb +4 -1
  37. data/spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb +177 -0
  38. data/spec/cypress_on_rails/vcr/use_cassette_middleware_spec.rb +68 -0
  39. data/specs_e2e/rails_6_1/.gitattributes +10 -0
  40. data/specs_e2e/rails_6_1/Gemfile +20 -0
  41. data/specs_e2e/{rails_5_2 → rails_6_1}/Rakefile +1 -1
  42. data/specs_e2e/rails_6_1/app/assets/stylesheets/application.css +15 -0
  43. data/specs_e2e/rails_6_1/app/jobs/application_job.rb +7 -0
  44. data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/layouts/application.html.erb +1 -1
  45. data/specs_e2e/rails_6_1/bin/bundle +114 -0
  46. data/specs_e2e/rails_6_1/bin/rails +5 -0
  47. data/specs_e2e/rails_6_1/bin/rake +5 -0
  48. data/specs_e2e/{rails_5_2 → rails_6_1}/bin/setup +15 -4
  49. data/specs_e2e/rails_6_1/bin/spring +14 -0
  50. data/specs_e2e/rails_6_1/bin/yarn +17 -0
  51. data/specs_e2e/rails_6_1/config/application.rb +34 -0
  52. data/specs_e2e/rails_6_1/config/boot.rb +4 -0
  53. data/specs_e2e/rails_6_1/config/cable.yml +10 -0
  54. data/specs_e2e/rails_6_1/config/credentials.yml.enc +1 -0
  55. data/specs_e2e/{rails_5_2 → rails_6_1}/config/database.yml +7 -0
  56. data/specs_e2e/{rails_5_2 → rails_6_1}/config/environment.rb +1 -1
  57. data/specs_e2e/{rails_5_2 → rails_6_1}/config/environments/development.rb +22 -5
  58. data/specs_e2e/rails_6_1/config/environments/production.rb +120 -0
  59. data/specs_e2e/{rails_5_2 → rails_6_1}/config/environments/test.rb +24 -7
  60. data/specs_e2e/rails_6_1/config/initializers/backtrace_silencers.rb +8 -0
  61. data/specs_e2e/{rails_5_2 → rails_6_1}/config/initializers/content_security_policy.rb +5 -0
  62. data/specs_e2e/{rails_4_2 → rails_6_1}/config/initializers/filter_parameter_logging.rb +3 -1
  63. data/specs_e2e/rails_6_1/config/initializers/permissions_policy.rb +11 -0
  64. data/specs_e2e/{rails_3_2 → rails_6_1}/config/initializers/wrap_parameters.rb +5 -1
  65. data/specs_e2e/{rails_5_2 → rails_6_1}/config/locales/en.yml +1 -1
  66. data/specs_e2e/rails_6_1/config/master.key +1 -0
  67. data/specs_e2e/rails_6_1/config/puma.rb +43 -0
  68. data/specs_e2e/rails_6_1/config/storage.yml +34 -0
  69. data/specs_e2e/{rails_5_2 → rails_6_1}/config.ru +2 -1
  70. data/specs_e2e/{rails_5_2 → rails_6_1}/db/migrate/20180621085832_create_posts.rb +1 -1
  71. data/specs_e2e/rails_6_1/package.json +8 -0
  72. data/specs_e2e/rails_6_1/playwright-report/index.html +71 -0
  73. data/specs_e2e/rails_6_1/public/robots.txt +1 -0
  74. data/specs_e2e/rails_6_1/test-results/.last-run.json +4 -0
  75. data/specs_e2e/{rails_4_2 → rails_6_1}/test.sh +22 -15
  76. data/specs_e2e/rails_7_2/.gitattributes +9 -0
  77. data/specs_e2e/rails_7_2/.gitignore +16 -0
  78. data/specs_e2e/rails_7_2/.rubocop.yml +8 -0
  79. data/specs_e2e/rails_7_2/Gemfile +11 -0
  80. data/specs_e2e/{rails_4_2 → rails_7_2}/Rakefile +1 -1
  81. data/specs_e2e/rails_7_2/app/assets/stylesheets/application.css +15 -0
  82. data/specs_e2e/rails_7_2/app/controllers/application_controller.rb +4 -0
  83. data/specs_e2e/rails_7_2/app/controllers/posts_controller.rb +58 -0
  84. data/specs_e2e/rails_7_2/app/helpers/posts_helper.rb +2 -0
  85. data/specs_e2e/rails_7_2/app/jobs/application_job.rb +7 -0
  86. data/specs_e2e/rails_7_2/app/models/application_record.rb +3 -0
  87. data/specs_e2e/rails_7_2/app/models/post.rb +2 -0
  88. data/specs_e2e/rails_7_2/app/views/layouts/application.html.erb +22 -0
  89. data/specs_e2e/rails_7_2/app/views/posts/_form.html.erb +32 -0
  90. data/specs_e2e/rails_7_2/app/views/posts/edit.html.erb +6 -0
  91. data/specs_e2e/rails_7_2/app/views/posts/index.html.erb +31 -0
  92. data/specs_e2e/rails_7_2/app/views/posts/new.html.erb +5 -0
  93. data/specs_e2e/rails_7_2/app/views/posts/show.html.erb +19 -0
  94. data/specs_e2e/rails_7_2/bin/brakeman +7 -0
  95. data/specs_e2e/rails_7_2/bin/bundle +109 -0
  96. data/specs_e2e/rails_7_2/bin/importmap +4 -0
  97. data/specs_e2e/rails_7_2/bin/rails +4 -0
  98. data/specs_e2e/rails_7_2/bin/rake +4 -0
  99. data/specs_e2e/rails_7_2/bin/setup +37 -0
  100. data/specs_e2e/rails_7_2/config/application.rb +37 -0
  101. data/specs_e2e/rails_7_2/config/boot.rb +4 -0
  102. data/specs_e2e/rails_7_2/config/cable.yml +10 -0
  103. data/specs_e2e/rails_7_2/config/credentials.yml.enc +1 -0
  104. data/specs_e2e/rails_7_2/config/database.yml +32 -0
  105. data/specs_e2e/{rails_4_2 → rails_7_2}/config/environment.rb +1 -1
  106. data/specs_e2e/rails_7_2/config/environments/development.rb +54 -0
  107. data/specs_e2e/rails_7_2/config/environments/production.rb +105 -0
  108. data/specs_e2e/rails_7_2/config/environments/test.rb +45 -0
  109. data/specs_e2e/rails_7_2/config/importmap.rb +7 -0
  110. data/specs_e2e/rails_7_2/config/initializers/content_security_policy.rb +25 -0
  111. data/specs_e2e/rails_7_2/config/initializers/filter_parameter_logging.rb +8 -0
  112. data/specs_e2e/{rails_5_2 → rails_7_2}/config/initializers/inflections.rb +4 -4
  113. data/specs_e2e/rails_7_2/config/initializers/permissions_policy.rb +13 -0
  114. data/specs_e2e/rails_7_2/config/locales/en.yml +31 -0
  115. data/specs_e2e/rails_7_2/config/master.key +1 -0
  116. data/specs_e2e/rails_7_2/config/puma.rb +34 -0
  117. data/specs_e2e/rails_7_2/config/routes.rb +5 -0
  118. data/specs_e2e/rails_7_2/config/storage.yml +34 -0
  119. data/specs_e2e/{rails_4_2 → rails_7_2}/config.ru +3 -1
  120. data/specs_e2e/rails_7_2/db/migrate/20180621085832_create_posts.rb +11 -0
  121. data/specs_e2e/rails_7_2/db/seeds.rb +9 -0
  122. data/specs_e2e/rails_7_2/db/test.sqlite3-shm +0 -0
  123. data/specs_e2e/rails_7_2/db/test.sqlite3-wal +0 -0
  124. data/specs_e2e/rails_7_2/package.json +8 -0
  125. data/specs_e2e/rails_7_2/playwright-report/index.html +71 -0
  126. data/specs_e2e/{rails_4_2 → rails_7_2}/public/404.html +6 -6
  127. data/specs_e2e/rails_7_2/public/406-unsupported-browser.html +66 -0
  128. data/specs_e2e/{rails_4_2 → rails_7_2}/public/422.html +6 -6
  129. data/specs_e2e/{rails_4_2 → rails_7_2}/public/500.html +6 -6
  130. data/specs_e2e/rails_7_2/public/icon.png +0 -0
  131. data/specs_e2e/rails_7_2/public/icon.svg +3 -0
  132. data/specs_e2e/rails_7_2/public/robots.txt +1 -0
  133. data/specs_e2e/rails_7_2/storage/test.sqlite3 +0 -0
  134. data/specs_e2e/rails_7_2/test/controllers/posts_controller_test.rb +48 -0
  135. data/specs_e2e/rails_7_2/test/cypress_fixtures/posts.yml +11 -0
  136. data/specs_e2e/rails_7_2/test/fixtures/posts.yml +11 -0
  137. data/specs_e2e/rails_7_2/test/models/post_test.rb +7 -0
  138. data/specs_e2e/rails_7_2/test-results/.last-run.json +4 -0
  139. data/specs_e2e/rails_7_2/test.sh +57 -0
  140. data/specs_e2e/rails_8/.gitattributes +9 -0
  141. data/specs_e2e/rails_8/.gitignore +16 -0
  142. data/specs_e2e/rails_8/.rubocop.yml +8 -0
  143. data/specs_e2e/rails_8/Gemfile +20 -0
  144. data/specs_e2e/{rails_3_2 → rails_8}/Rakefile +2 -3
  145. data/specs_e2e/rails_8/app/assets/stylesheets/application.css +10 -0
  146. data/specs_e2e/rails_8/app/controllers/application_controller.rb +4 -0
  147. data/specs_e2e/rails_8/app/controllers/posts_controller.rb +58 -0
  148. data/specs_e2e/rails_8/app/helpers/posts_helper.rb +2 -0
  149. data/specs_e2e/rails_8/app/jobs/application_job.rb +7 -0
  150. data/specs_e2e/rails_8/app/models/application_record.rb +3 -0
  151. data/specs_e2e/rails_8/app/models/post.rb +2 -0
  152. data/specs_e2e/rails_8/app/views/layouts/application.html.erb +27 -0
  153. data/specs_e2e/rails_8/app/views/posts/_form.html.erb +32 -0
  154. data/specs_e2e/rails_8/app/views/posts/edit.html.erb +6 -0
  155. data/specs_e2e/rails_8/app/views/posts/index.html.erb +31 -0
  156. data/specs_e2e/rails_8/app/views/posts/new.html.erb +5 -0
  157. data/specs_e2e/rails_8/app/views/posts/show.html.erb +19 -0
  158. data/specs_e2e/rails_8/bin/brakeman +7 -0
  159. data/specs_e2e/rails_8/bin/bundle +109 -0
  160. data/specs_e2e/rails_8/bin/dev +2 -0
  161. data/specs_e2e/rails_8/bin/importmap +4 -0
  162. data/specs_e2e/rails_8/bin/rails +4 -0
  163. data/specs_e2e/rails_8/bin/rake +4 -0
  164. data/specs_e2e/rails_8/bin/setup +34 -0
  165. data/specs_e2e/rails_8/bin/thrust +5 -0
  166. data/specs_e2e/rails_8/config/application.rb +27 -0
  167. data/specs_e2e/rails_8/config/boot.rb +4 -0
  168. data/specs_e2e/rails_8/config/cable.yml +17 -0
  169. data/specs_e2e/rails_8/config/cache.yml +16 -0
  170. data/specs_e2e/rails_8/config/credentials.yml.enc +1 -0
  171. data/specs_e2e/rails_8/config/database.yml +41 -0
  172. data/specs_e2e/rails_8/config/deploy.yml +116 -0
  173. data/specs_e2e/rails_8/config/environment.rb +5 -0
  174. data/specs_e2e/rails_8/config/environments/development.rb +57 -0
  175. data/specs_e2e/rails_8/config/environments/production.rb +90 -0
  176. data/specs_e2e/rails_8/config/environments/test.rb +45 -0
  177. data/specs_e2e/rails_8/config/importmap.rb +7 -0
  178. data/specs_e2e/rails_8/config/initializers/content_security_policy.rb +25 -0
  179. data/specs_e2e/rails_8/config/initializers/filter_parameter_logging.rb +8 -0
  180. data/specs_e2e/rails_8/config/initializers/inflections.rb +16 -0
  181. data/specs_e2e/rails_8/config/locales/en.yml +31 -0
  182. data/specs_e2e/rails_8/config/master.key +1 -0
  183. data/specs_e2e/rails_8/config/puma.rb +41 -0
  184. data/specs_e2e/rails_8/config/queue.yml +18 -0
  185. data/specs_e2e/rails_8/config/recurring.yml +10 -0
  186. data/specs_e2e/rails_8/config/routes.rb +5 -0
  187. data/specs_e2e/rails_8/config/storage.yml +34 -0
  188. data/specs_e2e/rails_8/config.ru +6 -0
  189. data/specs_e2e/rails_8/db/cable_schema.rb +11 -0
  190. data/specs_e2e/rails_8/db/cache_schema.rb +14 -0
  191. data/specs_e2e/rails_8/db/migrate/20180621085832_create_posts.rb +11 -0
  192. data/specs_e2e/rails_8/db/queue_schema.rb +129 -0
  193. data/specs_e2e/rails_8/db/seeds.rb +9 -0
  194. data/specs_e2e/rails_8/package.json +8 -0
  195. data/specs_e2e/rails_8/playwright-report/index.html +71 -0
  196. data/specs_e2e/rails_8/public/400.html +114 -0
  197. data/specs_e2e/rails_8/public/404.html +114 -0
  198. data/specs_e2e/rails_8/public/406-unsupported-browser.html +114 -0
  199. data/specs_e2e/rails_8/public/422.html +114 -0
  200. data/specs_e2e/rails_8/public/500.html +114 -0
  201. data/specs_e2e/rails_8/public/icon.png +0 -0
  202. data/specs_e2e/rails_8/public/icon.svg +3 -0
  203. data/specs_e2e/rails_8/public/robots.txt +1 -0
  204. data/specs_e2e/rails_8/storage/test.sqlite3 +0 -0
  205. data/specs_e2e/rails_8/storage/test.sqlite3-shm +0 -0
  206. data/specs_e2e/rails_8/storage/test.sqlite3-wal +0 -0
  207. data/specs_e2e/rails_8/test/application_system_test_case.rb +5 -0
  208. data/specs_e2e/rails_8/test/controllers/posts_controller_test.rb +48 -0
  209. data/specs_e2e/rails_8/test/cypress_fixtures/posts.yml +11 -0
  210. data/specs_e2e/rails_8/test/fixtures/posts.yml +11 -0
  211. data/specs_e2e/rails_8/test/models/post_test.rb +7 -0
  212. data/specs_e2e/rails_8/test/test_helper.rb +15 -0
  213. data/specs_e2e/rails_8/test-results/.last-run.json +4 -0
  214. data/specs_e2e/{rails_5_2 → rails_8}/test.sh +1 -1
  215. metadata +246 -150
  216. data/lib/cypress_on_rails/vcr_middleware.rb +0 -73
  217. data/spec/cypress_on_rails/vcr_middleware_spec.rb +0 -119
  218. data/specs_e2e/rails_3_2/.gitignore +0 -9
  219. data/specs_e2e/rails_3_2/.ruby_version +0 -1
  220. data/specs_e2e/rails_3_2/Gemfile +0 -7
  221. data/specs_e2e/rails_3_2/README.rdoc +0 -261
  222. data/specs_e2e/rails_3_2/app/assets/stylesheets/application.css +0 -13
  223. data/specs_e2e/rails_3_2/app/controllers/application_controller.rb +0 -3
  224. data/specs_e2e/rails_3_2/app/controllers/welcome_controller.rb +0 -4
  225. data/specs_e2e/rails_3_2/app/helpers/application_helper.rb +0 -2
  226. data/specs_e2e/rails_3_2/app/models/post.rb +0 -21
  227. data/specs_e2e/rails_3_2/app/views/layouts/application.html.erb +0 -13
  228. data/specs_e2e/rails_3_2/app/views/welcome/index.html.erb +0 -24
  229. data/specs_e2e/rails_3_2/bin/rails +0 -6
  230. data/specs_e2e/rails_3_2/config/application.rb +0 -68
  231. data/specs_e2e/rails_3_2/config/boot.rb +0 -6
  232. data/specs_e2e/rails_3_2/config/environment.rb +0 -5
  233. data/specs_e2e/rails_3_2/config/environments/development.rb +0 -31
  234. data/specs_e2e/rails_3_2/config/environments/production.rb +0 -64
  235. data/specs_e2e/rails_3_2/config/environments/test.rb +0 -35
  236. data/specs_e2e/rails_3_2/config/initializers/backtrace_silencers.rb +0 -7
  237. data/specs_e2e/rails_3_2/config/initializers/inflections.rb +0 -15
  238. data/specs_e2e/rails_3_2/config/initializers/mime_types.rb +0 -5
  239. data/specs_e2e/rails_3_2/config/initializers/secret_token.rb +0 -7
  240. data/specs_e2e/rails_3_2/config/initializers/session_store.rb +0 -8
  241. data/specs_e2e/rails_3_2/config/locales/en.yml +0 -5
  242. data/specs_e2e/rails_3_2/config/routes.rb +0 -60
  243. data/specs_e2e/rails_3_2/config.ru +0 -4
  244. data/specs_e2e/rails_3_2/public/404.html +0 -26
  245. data/specs_e2e/rails_3_2/public/422.html +0 -26
  246. data/specs_e2e/rails_3_2/public/500.html +0 -25
  247. data/specs_e2e/rails_3_2/public/robots.txt +0 -5
  248. data/specs_e2e/rails_3_2/test.sh +0 -50
  249. data/specs_e2e/rails_4_2/.gitignore +0 -12
  250. data/specs_e2e/rails_4_2/Gemfile +0 -11
  251. data/specs_e2e/rails_4_2/README.rdoc +0 -28
  252. data/specs_e2e/rails_4_2/app/assets/javascripts/using_vcr.js +0 -2
  253. data/specs_e2e/rails_4_2/app/assets/stylesheets/using_vcr.css +0 -4
  254. data/specs_e2e/rails_4_2/app/controllers/application_controller.rb +0 -5
  255. data/specs_e2e/rails_4_2/app/controllers/using_vcr_controller.rb +0 -10
  256. data/specs_e2e/rails_4_2/app/controllers/welcome_controller.rb +0 -4
  257. data/specs_e2e/rails_4_2/app/models/post.rb +0 -23
  258. data/specs_e2e/rails_4_2/app/views/layouts/application.html.erb +0 -12
  259. data/specs_e2e/rails_4_2/app/views/using_vcr/index.html.erb +0 -6
  260. data/specs_e2e/rails_4_2/app/views/using_vcr/record_cats.html.erb +0 -7
  261. data/specs_e2e/rails_4_2/app/views/welcome/index.html.erb +0 -24
  262. data/specs_e2e/rails_4_2/bin/bundle +0 -3
  263. data/specs_e2e/rails_4_2/bin/rails +0 -4
  264. data/specs_e2e/rails_4_2/bin/rake +0 -4
  265. data/specs_e2e/rails_4_2/bin/setup +0 -29
  266. data/specs_e2e/rails_4_2/config/application.rb +0 -32
  267. data/specs_e2e/rails_4_2/config/boot.rb +0 -3
  268. data/specs_e2e/rails_4_2/config/environments/development.rb +0 -25
  269. data/specs_e2e/rails_4_2/config/environments/production.rb +0 -64
  270. data/specs_e2e/rails_4_2/config/environments/test.rb +0 -42
  271. data/specs_e2e/rails_4_2/config/initializers/backtrace_silencers.rb +0 -7
  272. data/specs_e2e/rails_4_2/config/initializers/cookies_serializer.rb +0 -3
  273. data/specs_e2e/rails_4_2/config/initializers/session_store.rb +0 -3
  274. data/specs_e2e/rails_4_2/config/initializers/to_time_preserves_timezone.rb +0 -10
  275. data/specs_e2e/rails_4_2/config/initializers/wrap_parameters.rb +0 -9
  276. data/specs_e2e/rails_4_2/config/locales/en.yml +0 -23
  277. data/specs_e2e/rails_4_2/config/routes.rb +0 -61
  278. data/specs_e2e/rails_4_2/config/secrets.yml +0 -22
  279. data/specs_e2e/rails_4_2/package.json +0 -12
  280. data/specs_e2e/rails_4_2/playwright-report/index.html +0 -62
  281. data/specs_e2e/rails_4_2/public/favicon.ico +0 -0
  282. data/specs_e2e/rails_4_2/public/robots.txt +0 -5
  283. data/specs_e2e/rails_4_2/spec/fixtures/vcr_cassettes/cats.yml +0 -63
  284. data/specs_e2e/rails_5_2/Gemfile +0 -15
  285. data/specs_e2e/rails_5_2/app/assets/javascripts/posts.js +0 -2
  286. data/specs_e2e/rails_5_2/app/assets/stylesheets/posts.css +0 -4
  287. data/specs_e2e/rails_5_2/app/assets/stylesheets/scaffold.css +0 -80
  288. data/specs_e2e/rails_5_2/app/jobs/application_job.rb +0 -2
  289. data/specs_e2e/rails_5_2/app/views/welcome/index.html.erb +0 -5
  290. data/specs_e2e/rails_5_2/bin/bundle +0 -3
  291. data/specs_e2e/rails_5_2/bin/rails +0 -4
  292. data/specs_e2e/rails_5_2/bin/rake +0 -4
  293. data/specs_e2e/rails_5_2/bin/update +0 -25
  294. data/specs_e2e/rails_5_2/config/application.rb +0 -33
  295. data/specs_e2e/rails_5_2/config/boot.rb +0 -4
  296. data/specs_e2e/rails_5_2/config/credentials.yml.enc +0 -1
  297. data/specs_e2e/rails_5_2/config/environments/production.rb +0 -68
  298. data/specs_e2e/rails_5_2/config/initializers/backtrace_silencers.rb +0 -7
  299. data/specs_e2e/rails_5_2/config/initializers/filter_parameter_logging.rb +0 -4
  300. data/specs_e2e/rails_5_2/config/initializers/mime_types.rb +0 -4
  301. data/specs_e2e/rails_5_2/config/initializers/wrap_parameters.rb +0 -9
  302. data/specs_e2e/rails_5_2/config/master.key +0 -1
  303. data/specs_e2e/rails_5_2/public/favicon.ico +0 -0
  304. data/specs_e2e/rails_5_2/public/robots.txt +0 -1
  305. /data/specs_e2e/{rails_5_2 → rails_6_1}/.gitignore +0 -0
  306. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/controllers/application_controller.rb +0 -0
  307. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/controllers/posts_controller.rb +0 -0
  308. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/helpers/posts_helper.rb +0 -0
  309. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/models/application_record.rb +0 -0
  310. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/models/post.rb +0 -0
  311. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/_form.html.erb +0 -0
  312. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/edit.html.erb +0 -0
  313. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/index.html.erb +0 -0
  314. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/new.html.erb +0 -0
  315. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/show.html.erb +0 -0
  316. /data/specs_e2e/{rails_5_2 → rails_6_1}/config/initializers/application_controller_renderer.rb +0 -0
  317. /data/specs_e2e/{rails_5_2 → rails_6_1}/config/initializers/cookies_serializer.rb +0 -0
  318. /data/specs_e2e/{rails_4_2 → rails_6_1}/config/initializers/inflections.rb +0 -0
  319. /data/specs_e2e/{rails_4_2 → rails_6_1}/config/initializers/mime_types.rb +0 -0
  320. /data/specs_e2e/{rails_5_2 → rails_6_1}/config/routes.rb +0 -0
  321. /data/specs_e2e/{rails_5_2 → rails_6_1}/public/404.html +0 -0
  322. /data/specs_e2e/{rails_5_2 → rails_6_1}/public/422.html +0 -0
  323. /data/specs_e2e/{rails_5_2 → rails_6_1}/public/500.html +0 -0
  324. /data/specs_e2e/{rails_5_2 → rails_6_1}/public/apple-touch-icon-precomposed.png +0 -0
  325. /data/specs_e2e/{rails_5_2 → rails_6_1}/public/apple-touch-icon.png +0 -0
  326. /data/specs_e2e/{rails_3_2 → rails_6_1}/public/favicon.ico +0 -0
  327. /data/specs_e2e/{rails_5_2 → rails_6_1}/test/controllers/posts_controller_test.rb +0 -0
  328. /data/specs_e2e/{rails_5_2 → rails_6_1}/test/cypress_fixtures/posts.yml +0 -0
  329. /data/specs_e2e/{rails_5_2 → rails_6_1}/test/fixtures/posts.yml +0 -0
  330. /data/specs_e2e/{rails_5_2 → rails_6_1}/test/models/post_test.rb +0 -0
  331. /data/specs_e2e/{rails_3_2/log → rails_6_1/vendor}/.keep +0 -0
  332. /data/specs_e2e/{rails_3_2/tmp → rails_7_2/vendor}/.keep +0 -0
  333. /data/specs_e2e/{rails_4_2/spec → rails_7_2/vendor/javascript}/.keep +0 -0
  334. /data/specs_e2e/{rails_5_2 → rails_8}/README.md +0 -0
  335. /data/specs_e2e/{rails_4_2/vendor → rails_8/storage}/.keep +0 -0
  336. /data/specs_e2e/{rails_5_2 → rails_8}/vendor/.keep +0 -0
  337. /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
@@ -1,3 +1,3 @@
1
1
  module CypressOnRails
2
- VERSION = '1.17.0'.freeze
2
+ VERSION = '1.19.0'.freeze
3
3
  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 of removed these from other tests
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 of removed these from other tests
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
  })
@@ -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 of removed these from other tests
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: dont remove these command
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