cypress-on-rails 1.16.0 → 1.18.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 (323) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +14 -14
  3. data/.gitignore +2 -1
  4. data/CHANGELOG.md +11 -0
  5. data/README.md +202 -48
  6. data/cypress-on-rails.gemspec +1 -1
  7. data/docs/authentication.md +30 -0
  8. data/docs/factory_bot_associations.md +14 -0
  9. data/lib/cypress_on_rails/configuration.rb +5 -0
  10. data/lib/cypress_on_rails/middleware.rb +1 -0
  11. data/lib/cypress_on_rails/railtie.rb +10 -2
  12. data/lib/cypress_on_rails/simple_rails_factory.rb +0 -2
  13. data/lib/cypress_on_rails/vcr/insert_eject_middleware.rb +75 -0
  14. data/lib/cypress_on_rails/vcr/middleware_helpers.rb +51 -0
  15. data/lib/cypress_on_rails/vcr/use_cassette_middleware.rb +56 -0
  16. data/lib/cypress_on_rails/version.rb +1 -1
  17. data/lib/generators/cypress_on_rails/install_generator.rb +31 -29
  18. data/lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb +9 -1
  19. data/lib/generators/cypress_on_rails/templates/spec/cypress/support/commands.js +22 -0
  20. data/lib/generators/cypress_on_rails/templates/spec/cypress/support/on-rails.js +7 -0
  21. data/lib/generators/cypress_on_rails/templates/spec/e2e/e2e_helper.rb.erb +0 -5
  22. data/spec/cypress_on_rails/configuration_spec.rb +4 -1
  23. data/spec/cypress_on_rails/vcr/insert_eject_middleware_spec.rb +177 -0
  24. data/spec/cypress_on_rails/vcr/use_cassette_middleware_spec.rb +68 -0
  25. data/specs_e2e/rails_6_1/.gitattributes +10 -0
  26. data/specs_e2e/{rails_5_2 → rails_6_1}/.gitignore +4 -0
  27. data/specs_e2e/rails_6_1/Gemfile +20 -0
  28. data/specs_e2e/{rails_5_2 → rails_6_1}/Rakefile +1 -1
  29. data/specs_e2e/rails_6_1/app/assets/stylesheets/application.css +15 -0
  30. data/specs_e2e/rails_6_1/app/jobs/application_job.rb +7 -0
  31. data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/layouts/application.html.erb +1 -1
  32. data/specs_e2e/rails_6_1/bin/bundle +114 -0
  33. data/specs_e2e/rails_6_1/bin/rails +5 -0
  34. data/specs_e2e/rails_6_1/bin/rake +5 -0
  35. data/specs_e2e/{rails_5_2 → rails_6_1}/bin/setup +15 -4
  36. data/specs_e2e/rails_6_1/bin/spring +14 -0
  37. data/specs_e2e/rails_6_1/bin/yarn +17 -0
  38. data/specs_e2e/rails_6_1/config/application.rb +34 -0
  39. data/specs_e2e/rails_6_1/config/boot.rb +4 -0
  40. data/specs_e2e/rails_6_1/config/cable.yml +10 -0
  41. data/specs_e2e/rails_6_1/config/credentials.yml.enc +1 -0
  42. data/specs_e2e/{rails_5_2 → rails_6_1}/config/database.yml +7 -0
  43. data/specs_e2e/{rails_5_2 → rails_6_1}/config/environment.rb +1 -1
  44. data/specs_e2e/{rails_5_2 → rails_6_1}/config/environments/development.rb +22 -5
  45. data/specs_e2e/rails_6_1/config/environments/production.rb +120 -0
  46. data/specs_e2e/{rails_5_2 → rails_6_1}/config/environments/test.rb +24 -7
  47. data/specs_e2e/rails_6_1/config/initializers/backtrace_silencers.rb +8 -0
  48. data/specs_e2e/{rails_5_2 → rails_6_1}/config/initializers/content_security_policy.rb +5 -0
  49. data/specs_e2e/{rails_4_2 → rails_6_1}/config/initializers/filter_parameter_logging.rb +3 -1
  50. data/specs_e2e/rails_6_1/config/initializers/permissions_policy.rb +11 -0
  51. data/specs_e2e/{rails_3_2 → rails_6_1}/config/initializers/wrap_parameters.rb +5 -1
  52. data/specs_e2e/{rails_5_2 → rails_6_1}/config/locales/en.yml +1 -1
  53. data/specs_e2e/rails_6_1/config/master.key +1 -0
  54. data/specs_e2e/rails_6_1/config/puma.rb +43 -0
  55. data/specs_e2e/rails_6_1/config/storage.yml +34 -0
  56. data/specs_e2e/{rails_5_2 → rails_6_1}/config.ru +2 -1
  57. data/specs_e2e/{rails_5_2 → rails_6_1}/db/migrate/20180621085832_create_posts.rb +1 -1
  58. data/specs_e2e/rails_6_1/package.json +8 -0
  59. data/specs_e2e/rails_6_1/playwright-report/index.html +71 -0
  60. data/specs_e2e/rails_6_1/public/robots.txt +1 -0
  61. data/specs_e2e/rails_6_1/test-results/.last-run.json +4 -0
  62. data/specs_e2e/rails_6_1/test.sh +57 -0
  63. data/specs_e2e/rails_7_2/.gitattributes +9 -0
  64. data/specs_e2e/rails_7_2/.gitignore +16 -0
  65. data/specs_e2e/rails_7_2/.rubocop.yml +8 -0
  66. data/specs_e2e/rails_7_2/Gemfile +11 -0
  67. data/specs_e2e/{rails_4_2 → rails_7_2}/Rakefile +1 -1
  68. data/specs_e2e/rails_7_2/app/assets/stylesheets/application.css +15 -0
  69. data/specs_e2e/rails_7_2/app/controllers/application_controller.rb +4 -0
  70. data/specs_e2e/rails_7_2/app/controllers/posts_controller.rb +58 -0
  71. data/specs_e2e/rails_7_2/app/helpers/posts_helper.rb +2 -0
  72. data/specs_e2e/rails_7_2/app/jobs/application_job.rb +7 -0
  73. data/specs_e2e/rails_7_2/app/models/application_record.rb +3 -0
  74. data/specs_e2e/rails_7_2/app/models/post.rb +2 -0
  75. data/specs_e2e/rails_7_2/app/views/layouts/application.html.erb +22 -0
  76. data/specs_e2e/rails_7_2/app/views/posts/_form.html.erb +32 -0
  77. data/specs_e2e/rails_7_2/app/views/posts/edit.html.erb +6 -0
  78. data/specs_e2e/rails_7_2/app/views/posts/index.html.erb +31 -0
  79. data/specs_e2e/rails_7_2/app/views/posts/new.html.erb +5 -0
  80. data/specs_e2e/rails_7_2/app/views/posts/show.html.erb +19 -0
  81. data/specs_e2e/rails_7_2/bin/brakeman +7 -0
  82. data/specs_e2e/rails_7_2/bin/bundle +109 -0
  83. data/specs_e2e/rails_7_2/bin/importmap +4 -0
  84. data/specs_e2e/rails_7_2/bin/rails +4 -0
  85. data/specs_e2e/rails_7_2/bin/rake +4 -0
  86. data/specs_e2e/rails_7_2/bin/setup +37 -0
  87. data/specs_e2e/rails_7_2/config/application.rb +37 -0
  88. data/specs_e2e/rails_7_2/config/boot.rb +4 -0
  89. data/specs_e2e/rails_7_2/config/cable.yml +10 -0
  90. data/specs_e2e/rails_7_2/config/credentials.yml.enc +1 -0
  91. data/specs_e2e/rails_7_2/config/database.yml +32 -0
  92. data/specs_e2e/{rails_4_2 → rails_7_2}/config/environment.rb +1 -1
  93. data/specs_e2e/rails_7_2/config/environments/development.rb +54 -0
  94. data/specs_e2e/rails_7_2/config/environments/production.rb +105 -0
  95. data/specs_e2e/rails_7_2/config/environments/test.rb +45 -0
  96. data/specs_e2e/rails_7_2/config/importmap.rb +7 -0
  97. data/specs_e2e/rails_7_2/config/initializers/content_security_policy.rb +25 -0
  98. data/specs_e2e/rails_7_2/config/initializers/filter_parameter_logging.rb +8 -0
  99. data/specs_e2e/{rails_5_2 → rails_7_2}/config/initializers/inflections.rb +4 -4
  100. data/specs_e2e/rails_7_2/config/initializers/permissions_policy.rb +13 -0
  101. data/specs_e2e/rails_7_2/config/locales/en.yml +31 -0
  102. data/specs_e2e/rails_7_2/config/master.key +1 -0
  103. data/specs_e2e/rails_7_2/config/puma.rb +34 -0
  104. data/specs_e2e/rails_7_2/config/routes.rb +5 -0
  105. data/specs_e2e/rails_7_2/config/storage.yml +34 -0
  106. data/specs_e2e/{rails_4_2 → rails_7_2}/config.ru +3 -1
  107. data/specs_e2e/rails_7_2/db/migrate/20180621085832_create_posts.rb +11 -0
  108. data/specs_e2e/rails_7_2/db/seeds.rb +9 -0
  109. data/specs_e2e/rails_7_2/db/test.sqlite3-shm +0 -0
  110. data/specs_e2e/rails_7_2/db/test.sqlite3-wal +0 -0
  111. data/specs_e2e/rails_7_2/package.json +8 -0
  112. data/specs_e2e/rails_7_2/playwright-report/index.html +71 -0
  113. data/specs_e2e/{rails_4_2 → rails_7_2}/public/404.html +6 -6
  114. data/specs_e2e/rails_7_2/public/406-unsupported-browser.html +66 -0
  115. data/specs_e2e/{rails_4_2 → rails_7_2}/public/422.html +6 -6
  116. data/specs_e2e/{rails_4_2 → rails_7_2}/public/500.html +6 -6
  117. data/specs_e2e/rails_7_2/public/icon.png +0 -0
  118. data/specs_e2e/rails_7_2/public/icon.svg +3 -0
  119. data/specs_e2e/rails_7_2/public/robots.txt +1 -0
  120. data/specs_e2e/rails_7_2/storage/test.sqlite3 +0 -0
  121. data/specs_e2e/rails_7_2/test/controllers/posts_controller_test.rb +48 -0
  122. data/specs_e2e/rails_7_2/test/cypress_fixtures/posts.yml +11 -0
  123. data/specs_e2e/rails_7_2/test/fixtures/posts.yml +11 -0
  124. data/specs_e2e/rails_7_2/test/models/post_test.rb +7 -0
  125. data/specs_e2e/rails_7_2/test-results/.last-run.json +4 -0
  126. data/specs_e2e/rails_7_2/test.sh +57 -0
  127. data/specs_e2e/rails_8/.gitattributes +9 -0
  128. data/specs_e2e/rails_8/.gitignore +16 -0
  129. data/specs_e2e/rails_8/.rubocop.yml +8 -0
  130. data/specs_e2e/rails_8/Gemfile +20 -0
  131. data/specs_e2e/{rails_3_2 → rails_8}/Rakefile +2 -3
  132. data/specs_e2e/rails_8/app/assets/stylesheets/application.css +10 -0
  133. data/specs_e2e/rails_8/app/controllers/application_controller.rb +4 -0
  134. data/specs_e2e/rails_8/app/controllers/posts_controller.rb +58 -0
  135. data/specs_e2e/rails_8/app/helpers/posts_helper.rb +2 -0
  136. data/specs_e2e/rails_8/app/jobs/application_job.rb +7 -0
  137. data/specs_e2e/rails_8/app/models/application_record.rb +3 -0
  138. data/specs_e2e/rails_8/app/models/post.rb +2 -0
  139. data/specs_e2e/rails_8/app/views/layouts/application.html.erb +27 -0
  140. data/specs_e2e/rails_8/app/views/posts/_form.html.erb +32 -0
  141. data/specs_e2e/rails_8/app/views/posts/edit.html.erb +6 -0
  142. data/specs_e2e/rails_8/app/views/posts/index.html.erb +31 -0
  143. data/specs_e2e/rails_8/app/views/posts/new.html.erb +5 -0
  144. data/specs_e2e/rails_8/app/views/posts/show.html.erb +19 -0
  145. data/specs_e2e/rails_8/bin/brakeman +7 -0
  146. data/specs_e2e/rails_8/bin/bundle +109 -0
  147. data/specs_e2e/rails_8/bin/dev +2 -0
  148. data/specs_e2e/rails_8/bin/importmap +4 -0
  149. data/specs_e2e/rails_8/bin/rails +4 -0
  150. data/specs_e2e/rails_8/bin/rake +4 -0
  151. data/specs_e2e/rails_8/bin/setup +34 -0
  152. data/specs_e2e/rails_8/bin/thrust +5 -0
  153. data/specs_e2e/rails_8/config/application.rb +27 -0
  154. data/specs_e2e/rails_8/config/boot.rb +4 -0
  155. data/specs_e2e/rails_8/config/cable.yml +17 -0
  156. data/specs_e2e/rails_8/config/cache.yml +16 -0
  157. data/specs_e2e/rails_8/config/credentials.yml.enc +1 -0
  158. data/specs_e2e/rails_8/config/database.yml +41 -0
  159. data/specs_e2e/rails_8/config/deploy.yml +116 -0
  160. data/specs_e2e/rails_8/config/environment.rb +5 -0
  161. data/specs_e2e/rails_8/config/environments/development.rb +57 -0
  162. data/specs_e2e/rails_8/config/environments/production.rb +90 -0
  163. data/specs_e2e/rails_8/config/environments/test.rb +45 -0
  164. data/specs_e2e/rails_8/config/importmap.rb +7 -0
  165. data/specs_e2e/rails_8/config/initializers/content_security_policy.rb +25 -0
  166. data/specs_e2e/rails_8/config/initializers/filter_parameter_logging.rb +8 -0
  167. data/specs_e2e/rails_8/config/initializers/inflections.rb +16 -0
  168. data/specs_e2e/rails_8/config/locales/en.yml +31 -0
  169. data/specs_e2e/rails_8/config/master.key +1 -0
  170. data/specs_e2e/rails_8/config/puma.rb +41 -0
  171. data/specs_e2e/rails_8/config/queue.yml +18 -0
  172. data/specs_e2e/rails_8/config/recurring.yml +10 -0
  173. data/specs_e2e/rails_8/config/routes.rb +5 -0
  174. data/specs_e2e/rails_8/config/storage.yml +34 -0
  175. data/specs_e2e/rails_8/config.ru +6 -0
  176. data/specs_e2e/rails_8/db/cable_schema.rb +11 -0
  177. data/specs_e2e/rails_8/db/cache_schema.rb +14 -0
  178. data/specs_e2e/rails_8/db/migrate/20180621085832_create_posts.rb +11 -0
  179. data/specs_e2e/rails_8/db/queue_schema.rb +129 -0
  180. data/specs_e2e/rails_8/db/seeds.rb +9 -0
  181. data/specs_e2e/rails_8/package.json +8 -0
  182. data/specs_e2e/rails_8/playwright-report/index.html +71 -0
  183. data/specs_e2e/rails_8/public/400.html +114 -0
  184. data/specs_e2e/rails_8/public/404.html +114 -0
  185. data/specs_e2e/rails_8/public/406-unsupported-browser.html +114 -0
  186. data/specs_e2e/rails_8/public/422.html +114 -0
  187. data/specs_e2e/rails_8/public/500.html +114 -0
  188. data/specs_e2e/rails_8/public/icon.png +0 -0
  189. data/specs_e2e/rails_8/public/icon.svg +3 -0
  190. data/specs_e2e/rails_8/public/robots.txt +1 -0
  191. data/specs_e2e/rails_8/storage/test.sqlite3 +0 -0
  192. data/specs_e2e/rails_8/storage/test.sqlite3-shm +0 -0
  193. data/specs_e2e/rails_8/storage/test.sqlite3-wal +0 -0
  194. data/specs_e2e/rails_8/test/application_system_test_case.rb +5 -0
  195. data/specs_e2e/rails_8/test/controllers/posts_controller_test.rb +48 -0
  196. data/specs_e2e/rails_8/test/cypress_fixtures/posts.yml +11 -0
  197. data/specs_e2e/rails_8/test/fixtures/posts.yml +11 -0
  198. data/specs_e2e/rails_8/test/models/post_test.rb +7 -0
  199. data/specs_e2e/rails_8/test/test_helper.rb +15 -0
  200. data/specs_e2e/rails_8/test-results/.last-run.json +4 -0
  201. data/specs_e2e/{rails_5_2 → rails_8}/test.sh +17 -8
  202. metadata +221 -153
  203. data/lib/cypress_on_rails/vcr_middleware.rb +0 -73
  204. data/lib/generators/cypress_on_rails/update_generator.rb +0 -24
  205. data/spec/cypress_on_rails/vcr_middleware_spec.rb +0 -119
  206. data/specs_e2e/rails_3_2/.gitignore +0 -9
  207. data/specs_e2e/rails_3_2/.ruby_version +0 -1
  208. data/specs_e2e/rails_3_2/Gemfile +0 -7
  209. data/specs_e2e/rails_3_2/README.rdoc +0 -261
  210. data/specs_e2e/rails_3_2/app/assets/stylesheets/application.css +0 -13
  211. data/specs_e2e/rails_3_2/app/controllers/application_controller.rb +0 -3
  212. data/specs_e2e/rails_3_2/app/controllers/welcome_controller.rb +0 -4
  213. data/specs_e2e/rails_3_2/app/helpers/application_helper.rb +0 -2
  214. data/specs_e2e/rails_3_2/app/models/post.rb +0 -21
  215. data/specs_e2e/rails_3_2/app/views/layouts/application.html.erb +0 -13
  216. data/specs_e2e/rails_3_2/app/views/welcome/index.html.erb +0 -24
  217. data/specs_e2e/rails_3_2/bin/rails +0 -6
  218. data/specs_e2e/rails_3_2/config/application.rb +0 -68
  219. data/specs_e2e/rails_3_2/config/boot.rb +0 -6
  220. data/specs_e2e/rails_3_2/config/environment.rb +0 -5
  221. data/specs_e2e/rails_3_2/config/environments/development.rb +0 -31
  222. data/specs_e2e/rails_3_2/config/environments/production.rb +0 -64
  223. data/specs_e2e/rails_3_2/config/environments/test.rb +0 -35
  224. data/specs_e2e/rails_3_2/config/initializers/backtrace_silencers.rb +0 -7
  225. data/specs_e2e/rails_3_2/config/initializers/inflections.rb +0 -15
  226. data/specs_e2e/rails_3_2/config/initializers/mime_types.rb +0 -5
  227. data/specs_e2e/rails_3_2/config/initializers/secret_token.rb +0 -7
  228. data/specs_e2e/rails_3_2/config/initializers/session_store.rb +0 -8
  229. data/specs_e2e/rails_3_2/config/locales/en.yml +0 -5
  230. data/specs_e2e/rails_3_2/config/routes.rb +0 -60
  231. data/specs_e2e/rails_3_2/config.ru +0 -4
  232. data/specs_e2e/rails_3_2/public/404.html +0 -26
  233. data/specs_e2e/rails_3_2/public/422.html +0 -26
  234. data/specs_e2e/rails_3_2/public/500.html +0 -25
  235. data/specs_e2e/rails_3_2/public/robots.txt +0 -5
  236. data/specs_e2e/rails_3_2/test.sh +0 -43
  237. data/specs_e2e/rails_4_2/.gitignore +0 -11
  238. data/specs_e2e/rails_4_2/Gemfile +0 -11
  239. data/specs_e2e/rails_4_2/README.rdoc +0 -28
  240. data/specs_e2e/rails_4_2/app/assets/javascripts/using_vcr.js +0 -2
  241. data/specs_e2e/rails_4_2/app/assets/stylesheets/using_vcr.css +0 -4
  242. data/specs_e2e/rails_4_2/app/controllers/application_controller.rb +0 -5
  243. data/specs_e2e/rails_4_2/app/controllers/using_vcr_controller.rb +0 -10
  244. data/specs_e2e/rails_4_2/app/controllers/welcome_controller.rb +0 -4
  245. data/specs_e2e/rails_4_2/app/models/post.rb +0 -23
  246. data/specs_e2e/rails_4_2/app/views/layouts/application.html.erb +0 -12
  247. data/specs_e2e/rails_4_2/app/views/using_vcr/index.html.erb +0 -6
  248. data/specs_e2e/rails_4_2/app/views/using_vcr/record_cats.html.erb +0 -7
  249. data/specs_e2e/rails_4_2/app/views/welcome/index.html.erb +0 -24
  250. data/specs_e2e/rails_4_2/bin/bundle +0 -3
  251. data/specs_e2e/rails_4_2/bin/rails +0 -4
  252. data/specs_e2e/rails_4_2/bin/rake +0 -4
  253. data/specs_e2e/rails_4_2/bin/setup +0 -29
  254. data/specs_e2e/rails_4_2/config/application.rb +0 -32
  255. data/specs_e2e/rails_4_2/config/boot.rb +0 -3
  256. data/specs_e2e/rails_4_2/config/environments/development.rb +0 -25
  257. data/specs_e2e/rails_4_2/config/environments/production.rb +0 -64
  258. data/specs_e2e/rails_4_2/config/environments/test.rb +0 -42
  259. data/specs_e2e/rails_4_2/config/initializers/backtrace_silencers.rb +0 -7
  260. data/specs_e2e/rails_4_2/config/initializers/cookies_serializer.rb +0 -3
  261. data/specs_e2e/rails_4_2/config/initializers/session_store.rb +0 -3
  262. data/specs_e2e/rails_4_2/config/initializers/to_time_preserves_timezone.rb +0 -10
  263. data/specs_e2e/rails_4_2/config/initializers/wrap_parameters.rb +0 -9
  264. data/specs_e2e/rails_4_2/config/locales/en.yml +0 -23
  265. data/specs_e2e/rails_4_2/config/routes.rb +0 -61
  266. data/specs_e2e/rails_4_2/config/secrets.yml +0 -22
  267. data/specs_e2e/rails_4_2/package.json +0 -10
  268. data/specs_e2e/rails_4_2/public/favicon.ico +0 -0
  269. data/specs_e2e/rails_4_2/public/robots.txt +0 -5
  270. data/specs_e2e/rails_4_2/test.sh +0 -44
  271. data/specs_e2e/rails_5_2/Gemfile +0 -15
  272. data/specs_e2e/rails_5_2/app/assets/javascripts/posts.js +0 -2
  273. data/specs_e2e/rails_5_2/app/assets/stylesheets/posts.css +0 -4
  274. data/specs_e2e/rails_5_2/app/assets/stylesheets/scaffold.css +0 -80
  275. data/specs_e2e/rails_5_2/app/jobs/application_job.rb +0 -2
  276. data/specs_e2e/rails_5_2/app/views/welcome/index.html.erb +0 -5
  277. data/specs_e2e/rails_5_2/bin/bundle +0 -3
  278. data/specs_e2e/rails_5_2/bin/rails +0 -4
  279. data/specs_e2e/rails_5_2/bin/rake +0 -4
  280. data/specs_e2e/rails_5_2/bin/update +0 -25
  281. data/specs_e2e/rails_5_2/config/application.rb +0 -33
  282. data/specs_e2e/rails_5_2/config/boot.rb +0 -4
  283. data/specs_e2e/rails_5_2/config/credentials.yml.enc +0 -1
  284. data/specs_e2e/rails_5_2/config/environments/production.rb +0 -68
  285. data/specs_e2e/rails_5_2/config/initializers/backtrace_silencers.rb +0 -7
  286. data/specs_e2e/rails_5_2/config/initializers/filter_parameter_logging.rb +0 -4
  287. data/specs_e2e/rails_5_2/config/initializers/mime_types.rb +0 -4
  288. data/specs_e2e/rails_5_2/config/initializers/wrap_parameters.rb +0 -9
  289. data/specs_e2e/rails_5_2/config/master.key +0 -1
  290. data/specs_e2e/rails_5_2/public/favicon.ico +0 -0
  291. data/specs_e2e/rails_5_2/public/robots.txt +0 -1
  292. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/controllers/application_controller.rb +0 -0
  293. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/controllers/posts_controller.rb +0 -0
  294. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/helpers/posts_helper.rb +0 -0
  295. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/models/application_record.rb +0 -0
  296. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/models/post.rb +0 -0
  297. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/_form.html.erb +0 -0
  298. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/edit.html.erb +0 -0
  299. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/index.html.erb +0 -0
  300. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/new.html.erb +0 -0
  301. /data/specs_e2e/{rails_5_2 → rails_6_1}/app/views/posts/show.html.erb +0 -0
  302. /data/specs_e2e/{rails_5_2 → rails_6_1}/config/initializers/application_controller_renderer.rb +0 -0
  303. /data/specs_e2e/{rails_5_2 → rails_6_1}/config/initializers/cookies_serializer.rb +0 -0
  304. /data/specs_e2e/{rails_4_2 → rails_6_1}/config/initializers/inflections.rb +0 -0
  305. /data/specs_e2e/{rails_4_2 → rails_6_1}/config/initializers/mime_types.rb +0 -0
  306. /data/specs_e2e/{rails_5_2 → rails_6_1}/config/routes.rb +0 -0
  307. /data/specs_e2e/{rails_5_2 → rails_6_1}/public/404.html +0 -0
  308. /data/specs_e2e/{rails_5_2 → rails_6_1}/public/422.html +0 -0
  309. /data/specs_e2e/{rails_5_2 → rails_6_1}/public/500.html +0 -0
  310. /data/specs_e2e/{rails_5_2 → rails_6_1}/public/apple-touch-icon-precomposed.png +0 -0
  311. /data/specs_e2e/{rails_5_2 → rails_6_1}/public/apple-touch-icon.png +0 -0
  312. /data/specs_e2e/{rails_3_2 → rails_6_1}/public/favicon.ico +0 -0
  313. /data/specs_e2e/{rails_5_2 → rails_6_1}/test/controllers/posts_controller_test.rb +0 -0
  314. /data/specs_e2e/{rails_5_2 → rails_6_1}/test/cypress_fixtures/posts.yml +0 -0
  315. /data/specs_e2e/{rails_5_2 → rails_6_1}/test/fixtures/posts.yml +0 -0
  316. /data/specs_e2e/{rails_5_2 → rails_6_1}/test/models/post_test.rb +0 -0
  317. /data/specs_e2e/{rails_3_2/log → rails_6_1/vendor}/.keep +0 -0
  318. /data/specs_e2e/{rails_3_2/tmp → rails_7_2/vendor}/.keep +0 -0
  319. /data/specs_e2e/{rails_4_2/spec → rails_7_2/vendor/javascript}/.keep +0 -0
  320. /data/specs_e2e/{rails_5_2 → rails_8}/README.md +0 -0
  321. /data/specs_e2e/{rails_4_2/vendor → rails_8/storage}/.keep +0 -0
  322. /data/specs_e2e/{rails_5_2 → rails_8}/vendor/.keep +0 -0
  323. /data/specs_e2e/{rails_3_2/vendor/.gitkeep → rails_8/vendor/javascript/.keep} +0 -0
@@ -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.16.0'.freeze
2
+ VERSION = '1.18.0'.freeze
3
3
  end
@@ -1,12 +1,9 @@
1
1
  module CypressOnRails
2
2
  class InstallGenerator < Rails::Generators::Base
3
3
  class_option :api_prefix, type: :string, default: ''
4
+ class_option :framework, type: :string, default: 'cypress'
4
5
  class_option :install_folder, type: :string, default: 'e2e'
5
- class_option :install_cypress, type: :boolean, default: true
6
- class_option :install_playwright, type: :boolean, default: false
7
6
  class_option :install_with, type: :string, default: 'yarn'
8
- class_option :cypress_folder, type: :string, default: 'cypress'
9
- class_option :playwright_folder, type: :string, default: 'playwright'
10
7
  class_option :experimental, type: :boolean, default: false
11
8
  source_root File.expand_path('../templates', __FILE__)
12
9
 
@@ -17,10 +14,11 @@ module CypressOnRails
17
14
 
18
15
  command = nil
19
16
  packages = []
20
-
21
- packages << 'cypress' if options.install_cypress
22
- packages.push('playwright', '@playwright/test') if options.install_playwright
23
-
17
+ packages = if options.framework == 'cypress'
18
+ ['cypress', 'cypress-on-rails']
19
+ elsif options.framework == 'playwright'
20
+ ['playwright', '@playwright/test']
21
+ end
24
22
  if options.install_with == 'yarn'
25
23
  command = "yarn --cwd=#{install_dir} add #{packages.join(' ')} --dev"
26
24
  elsif options.install_with == 'npm'
@@ -31,38 +29,42 @@ module CypressOnRails
31
29
  fail "failed to install #{packages.join(' ')}" unless system(command)
32
30
  end
33
31
 
34
- if options.install_cypress
35
- template "spec/cypress/support/index.js.erb", "#{options.cypress_folder}/support/index.js"
36
- copy_file "spec/cypress/support/commands.js", "#{options.cypress_folder}/support/commands.js"
37
- copy_file "spec/cypress.config.js", "#{options.cypress_folder}/../cypress.config.js"
32
+ if options.framework == 'cypress'
33
+ template "spec/cypress/support/index.js.erb", "#{options.install_folder}/cypress/support/index.js"
34
+ copy_file "spec/cypress/support/commands.js", "#{options.install_folder}/cypress/support/commands.js"
35
+ copy_file "spec/cypress.config.js", "#{options.install_folder}/cypress.config.js"
38
36
  end
39
- if options.install_playwright
40
- template "spec/playwright/support/index.js.erb", "#{options.playwright_folder}/support/index.js"
41
- copy_file "spec/playwright.config.js", "#{options.playwright_folder}/../playwright.config.js"
37
+ if options.framework == 'playwright'
38
+ template "spec/playwright/support/index.js.erb", "#{options.install_folder}/playwright/support/index.js"
39
+ copy_file "spec/playwright.config.js", "#{options.install_folder}/playwright.config.js"
42
40
  end
43
41
  end
44
42
 
45
43
  def add_initial_files
46
44
  template "config/initializers/cypress_on_rails.rb.erb", "config/initializers/cypress_on_rails.rb"
47
- template "spec/e2e/e2e_helper.rb.erb", "#{options.install_folder}/e2e_helper.rb"
48
- directory 'spec/e2e/app_commands', "#{options.install_folder}/app_commands"
49
- if options.install_cypress
50
- copy_file "spec/cypress/support/on-rails.js", "#{options.cypress_folder}/support/on-rails.js"
51
- directory 'spec/cypress/e2e/rails_examples', "#{options.cypress_folder}/e2e/rails_examples"
45
+ template "spec/e2e/e2e_helper.rb.erb", "#{options.install_folder}/#{options.framework}/e2e_helper.rb"
46
+ directory 'spec/e2e/app_commands', "#{options.install_folder}/#{options.framework}/app_commands"
47
+ if options.framework == 'cypress'
48
+ copy_file "spec/cypress/support/on-rails.js", "#{options.install_folder}/cypress/support/on-rails.js"
49
+ directory 'spec/cypress/e2e/rails_examples', "#{options.install_folder}/cypress/e2e/rails_examples"
52
50
  end
53
- if options.install_playwright
54
- copy_file "spec/playwright/support/on-rails.js", "#{options.playwright_folder}/support/on-rails.js"
55
- directory 'spec/playwright/e2e/rails_examples', "#{options.playwright_folder}/e2e/rails_examples"
51
+ if options.framework == 'playwright'
52
+ copy_file "spec/playwright/support/on-rails.js", "#{options.install_folder}/playwright/support/on-rails.js"
53
+ directory 'spec/playwright/e2e/rails_examples', "#{options.install_folder}/playwright/e2e/rails_examples"
56
54
  end
57
55
  end
58
56
 
59
57
  def update_files
60
- append_to_file "#{options.cypress_folder}/support/index.js",
61
- "\nimport './on-rails'",
62
- after: 'import \'./commands\''
63
- append_to_file "#{options.playwright_folder}/support/index.js",
64
- "\nimport './on-rails'",
65
- after: '// Import commands.js using ES2015 syntax:'
58
+ if options.framework == 'cypress'
59
+ append_to_file "#{options.install_folder}/cypress/support/index.js",
60
+ "\nimport './on-rails'",
61
+ after: 'import \'./commands\''
62
+ end
63
+ if options.framework == 'playwright'
64
+ append_to_file "#{options.install_folder}/playwright/support/index.js",
65
+ "\nimport './on-rails'",
66
+ after: '// Import commands.js using ES2015 syntax:'
67
+ end
66
68
  end
67
69
  end
68
70
  end
@@ -1,11 +1,19 @@
1
1
  if defined?(CypressOnRails)
2
2
  CypressOnRails.configure do |c|
3
3
  c.api_prefix = "<%= options.api_prefix %>"
4
- c.install_folder = File.expand_path("#{__dir__}/../../<%= options.install_folder %>")
4
+ c.install_folder = File.expand_path("#{__dir__}/../../<%= options.install_folder %>/<%= options.framework %>")
5
5
  # WARNING!! CypressOnRails can execute arbitrary ruby code
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
10
18
 
11
19
  # If you want to enable a before_request logic, such as authentication, logging, sending metrics, etc.
@@ -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
+ // });
@@ -6,6 +6,9 @@ Cypress.Commands.add('appCommands', function (body) {
6
6
  method: 'POST',
7
7
  url: "/__e2e__/command",
8
8
  body: JSON.stringify(body),
9
+ headers: {
10
+ 'Content-Type': 'application/json',
11
+ },
9
12
  log: false,
10
13
  failOnStatusCode: false
11
14
  }).then((response) => {
@@ -44,6 +47,7 @@ Cypress.Commands.add('appFixtures', function (options) {
44
47
  // The next is optional
45
48
  // beforeEach(() => {
46
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
47
51
  // });
48
52
 
49
53
  // comment this out if you do not want to attempt to log additional info on test fail
@@ -52,6 +56,9 @@ Cypress.on('fail', (err, runnable) => {
52
56
  Cypress.$.ajax({
53
57
  url: '/__e2e__/command',
54
58
  data: JSON.stringify({name: 'log_fail', options: {error_message: err.message, runnable_full_title: runnable.fullTitle() }}),
59
+ headers: {
60
+ 'Content-Type': 'application/json',
61
+ },
55
62
  async: false,
56
63
  method: 'POST'
57
64
  });
@@ -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
@@ -9,22 +9,25 @@ RSpec.describe CypressOnRails::Configuration do
9
9
  expect(CypressOnRails.configuration.use_middleware?).to eq(true)
10
10
  expect(CypressOnRails.configuration.logger).to_not be_nil
11
11
  expect(CypressOnRails.configuration.before_request).to_not be_nil
12
+ expect(CypressOnRails.configuration.vcr_options).to eq({})
12
13
  end
13
14
 
14
15
  it 'can be configured' do
15
16
  my_logger = Logger.new(STDOUT)
16
- before_request_lambda = -> (_) { return [200, {}, ['hello world']] }
17
+ before_request_lambda = ->(_) { return [200, {}, ['hello world']] }
17
18
  CypressOnRails.configure do |config|
18
19
  config.api_prefix = '/api'
19
20
  config.install_folder = 'my/path'
20
21
  config.use_middleware = false
21
22
  config.logger = my_logger
22
23
  config.before_request = before_request_lambda
24
+ config.vcr_options = { hook_into: :webmock }
23
25
  end
24
26
  expect(CypressOnRails.configuration.api_prefix).to eq('/api')
25
27
  expect(CypressOnRails.configuration.install_folder).to eq('my/path')
26
28
  expect(CypressOnRails.configuration.use_middleware?).to eq(false)
27
29
  expect(CypressOnRails.configuration.logger).to eq(my_logger)
28
30
  expect(CypressOnRails.configuration.before_request).to eq(before_request_lambda)
31
+ expect(CypressOnRails.configuration.vcr_options).to eq(hook_into: :webmock)
29
32
  end
30
33
  end
@@ -0,0 +1,177 @@
1
+ require 'cypress_on_rails/vcr/insert_eject_middleware'
2
+ require 'vcr'
3
+ require 'active_support/core_ext/hash' unless {}.respond_to?(:symbolize_keys)
4
+
5
+ module CypressOnRails
6
+ module Vcr
7
+ RSpec.describe InsertEjectMiddleware do
8
+ let(:app) { ->(env) { [200, {}, ["app did #{env['PATH_INFO']}"]] } }
9
+ let(:vcr) { class_double(VCR, turn_on!: true, turn_off!: true, insert_cassette: true, eject_cassette: true) }
10
+ subject { described_class.new(app, vcr) }
11
+
12
+ let(:env) { {} }
13
+
14
+ let(:response) { subject.call(env) }
15
+
16
+ def rack_input(json_value)
17
+ StringIO.new(JSON.generate(json_value))
18
+ end
19
+
20
+ describe '/__e2e__/vcr/insert' do
21
+ before do
22
+ env['PATH_INFO'] = '/__e2e__/vcr/insert'
23
+ end
24
+
25
+ it do
26
+ env['rack.input'] = rack_input(['cas1'])
27
+
28
+ aggregate_failures do
29
+ expect(response).to eq([201,
30
+ { 'Content-Type' => 'application/json' },
31
+ ['{"message":"OK"}']])
32
+ expect(vcr).to have_received(:turn_on!)
33
+ expect(vcr).to have_received(:insert_cassette).with('cas1', {})
34
+ end
35
+ end
36
+
37
+ it 'works with record' do
38
+ env['rack.input'] = rack_input(['cas1', { 'record' => 'new_episodes' }])
39
+
40
+ aggregate_failures do
41
+ expect(response).to eq([201,
42
+ { 'Content-Type' => 'application/json' },
43
+ ['{"message":"OK"}']])
44
+ expect(vcr).to have_received(:insert_cassette).with('cas1', record: :new_episodes)
45
+ end
46
+ end
47
+
48
+ it 'works with match_requests_on' do
49
+ env['rack.input'] = rack_input(['cas1', { 'match_requests_on' => %w[method uri] }])
50
+
51
+ aggregate_failures do
52
+ expect(response).to eq([201,
53
+ { 'Content-Type' => 'application/json' },
54
+ ['{"message":"OK"}']])
55
+ expect(vcr).to have_received(:insert_cassette).with('cas1', match_requests_on: %i[method uri])
56
+ end
57
+ end
58
+
59
+ it 'works with serialize_with' do
60
+ env['rack.input'] = rack_input(['cas1', { 'serialize_with' => 'yaml' }])
61
+
62
+ aggregate_failures do
63
+ expect(response).to eq([201,
64
+ { 'Content-Type' => 'application/json' },
65
+ ['{"message":"OK"}']])
66
+ expect(vcr).to have_received(:insert_cassette).with('cas1', serialize_with: :yaml)
67
+ end
68
+ end
69
+
70
+ it 'works with persist_with' do
71
+ env['rack.input'] = rack_input(['cas1', { 'persist_with' => 'file_system' }])
72
+
73
+ aggregate_failures do
74
+ expect(response).to eq([201,
75
+ { 'Content-Type' => 'application/json' },
76
+ ['{"message":"OK"}']])
77
+ expect(vcr).to have_received(:insert_cassette).with('cas1', persist_with: :file_system)
78
+ end
79
+ end
80
+
81
+ context 'when an error occurs' do
82
+ it 'returns a 500 error with the error message' do
83
+ env['rack.input'] = rack_input(['cas1'])
84
+ allow(vcr).to receive(:insert_cassette).and_raise(ArgumentError.new('Invalid cassette name'))
85
+
86
+ expect(response).to eq([
87
+ 500,
88
+ { 'Content-Type' => 'application/json' },
89
+ ['{"message":"Invalid cassette name"}']
90
+ ])
91
+ end
92
+
93
+ it 'returns a 500 error when LoadError occurs' do
94
+ env['rack.input'] = rack_input(['cas1'])
95
+ allow(vcr).to receive(:insert_cassette).and_raise(LoadError.new('Cannot load VCR'))
96
+
97
+ expect(response).to eq([
98
+ 500,
99
+ { 'Content-Type' => 'application/json' },
100
+ ['{"message":"Cannot load VCR"}']
101
+ ])
102
+ end
103
+ end
104
+
105
+ it 'returns a 400 error when JSON parsing fails' do
106
+ env['rack.input'] = StringIO.new('invalid json')
107
+
108
+ expect(response).to eq([
109
+ 400,
110
+ { 'Content-Type' => 'application/json' },
111
+ ['{"message":"unexpected token at \'invalid json\'"}']
112
+ ])
113
+ end
114
+ end
115
+
116
+ describe '/__e2e__/vcr/eject' do
117
+ before do
118
+ env['PATH_INFO'] = '/__e2e__/vcr/eject'
119
+ end
120
+
121
+ it do
122
+ aggregate_failures do
123
+ expect(response).to eq([201,
124
+ { 'Content-Type' => 'application/json' },
125
+ ['{"message":"OK"}']])
126
+ expect(vcr).to have_received(:turn_off!)
127
+ expect(vcr).to have_received(:eject_cassette)
128
+ end
129
+ end
130
+
131
+ context 'when an error occurs' do
132
+ it 'returns a 500 error with the error message' do
133
+ allow(vcr).to receive(:eject_cassette).and_raise(ArgumentError.new('No cassette to eject'))
134
+
135
+ expect(response).to eq([
136
+ 500,
137
+ { 'Content-Type' => 'application/json' },
138
+ ['{"message":"No cassette to eject"}']
139
+ ])
140
+ end
141
+
142
+ it 'returns a 500 error when LoadError occurs' do
143
+ allow(vcr).to receive(:eject_cassette).and_raise(LoadError.new('Cannot load VCR'))
144
+
145
+ expect(response).to eq([
146
+ 500,
147
+ { 'Content-Type' => 'application/json' },
148
+ ['{"message":"Cannot load VCR"}']
149
+ ])
150
+ end
151
+ end
152
+ end
153
+
154
+ describe '"Other paths"' do
155
+ it 'calls vcr turn off the first time' do
156
+ env['PATH_INFO'] = '/test'
157
+
158
+ expect(response).to eq([200, {}, ['app did /test']])
159
+ expect(vcr).to have_received(:turn_off!)
160
+ end
161
+
162
+ it 'runs app' do
163
+ aggregate_failures do
164
+ %w[/ /__e2e__/login command /e2e_command /].each do |path|
165
+ env['PATH_INFO'] = path
166
+
167
+ response = subject.call(env)
168
+
169
+ expect(response).to eq([200, {}, ["app did #{path}"]])
170
+ expect(vcr).to have_received(:turn_off!)
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,68 @@
1
+ require 'cypress_on_rails/vcr/use_cassette_middleware'
2
+ require 'vcr'
3
+ require 'active_support/core_ext/hash' unless {}.respond_to?(:symbolize_keys)
4
+
5
+ module CypressOnRails
6
+ module Vcr
7
+ RSpec.describe UseCassetteMiddleware do
8
+ let(:app) { ->(env) { [200, {}, ["app did #{env['PATH_INFO']}"]] } }
9
+ let(:vcr) { VCR }
10
+ subject { described_class.new(app, vcr) }
11
+
12
+ let(:env) { { 'rack.input' => rack_input([]) } }
13
+
14
+ let(:response) { subject.call(env) }
15
+
16
+ def rack_input(json_value)
17
+ StringIO.new(JSON.generate(json_value))
18
+ end
19
+
20
+ before do
21
+ allow(vcr).to receive(:use_cassette).and_yield
22
+ end
23
+
24
+ it 'returns the application response using correct graphql cassette' do
25
+ env['PATH_INFO'] = '/graphql'
26
+ env['QUERY_STRING'] = 'operation=test'
27
+
28
+ expect(response).to eq([200, {}, ['app did /graphql']])
29
+ expect(vcr).to have_received(:use_cassette).with('/graphql/test')
30
+ end
31
+
32
+ it 'returns the application response using default request path cassette' do
33
+ allow(CypressOnRails).to receive(:configuration).and_return(double(logger: Logger.new(nil)))
34
+ env['PATH_INFO'] = '/test/path'
35
+
36
+ expect(response).to eq([200, {}, ['app did /test/path']])
37
+ expect(vcr).to have_received(:use_cassette).with('/test/path')
38
+ end
39
+
40
+ context 'when VCR cassette library directory does not match' do
41
+ before do
42
+ allow(VCR.configuration).to receive(:cassette_library_dir).and_return('/different/path')
43
+ end
44
+
45
+ it 'returns the application response without using VCR' do
46
+ env['PATH_INFO'] = '/test/path'
47
+
48
+ expect(response).to eq([200, {}, ['app did /test/path']])
49
+ expect(vcr).not_to have_received(:use_cassette)
50
+ end
51
+ end
52
+
53
+ context 'when VCR is not defined' do
54
+ before do
55
+ allow(subject).to receive(:vcr_defined?).and_return(false)
56
+ end
57
+
58
+ it 'returns the application response without error' do
59
+ env['PATH_INFO'] = '/graphql'
60
+ env['QUERY_STRING'] = 'operation=test'
61
+
62
+ expect(response).to eq([200, {}, ['app did /graphql']])
63
+ expect(vcr).to have_received(:use_cassette).with('/graphql/test')
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,10 @@
1
+ # See https://git-scm.com/docs/gitattributes for more about git attribute files.
2
+
3
+ # Mark the database schema as having been generated.
4
+ db/schema.rb linguist-generated
5
+
6
+ # Mark the yarn lockfile as having been generated.
7
+ yarn.lock linguist-generated
8
+
9
+ # Mark any vendored files as having been vendored.
10
+ vendor/* linguist-vendored