cypress-on-rails 1.10.1 → 1.15.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +63 -0
  3. data/.gitignore +5 -1
  4. data/CHANGELOG.md +65 -2
  5. data/README.md +261 -62
  6. data/cypress-on-rails.gemspec +1 -0
  7. data/docs/authentication.md +12 -10
  8. data/docs/factory_bot_associations.md +109 -0
  9. data/lib/cypress-on-rails.rb +2 -2
  10. data/lib/cypress_on_rails/command_executor.rb +9 -5
  11. data/lib/cypress_on_rails/configuration.rb +17 -2
  12. data/lib/cypress_on_rails/middleware.rb +15 -16
  13. data/lib/cypress_on_rails/middleware_config.rb +17 -0
  14. data/lib/cypress_on_rails/railtie.rb +5 -1
  15. data/lib/cypress_on_rails/smart_factory_wrapper.rb +49 -14
  16. data/lib/cypress_on_rails/vcr_middleware.rb +73 -0
  17. data/lib/cypress_on_rails/version.rb +1 -1
  18. data/lib/generators/cypress_on_rails/install_generator.rb +48 -30
  19. data/lib/generators/cypress_on_rails/templates/config/initializers/cypress_on_rails.rb.erb +3 -1
  20. data/lib/generators/cypress_on_rails/templates/spec/cypress/{integration/rails_examples/advance_factory_bot_spec.js → e2e/rails_examples/advance_factory_bot.cy.js} +1 -1
  21. data/lib/generators/cypress_on_rails/templates/spec/cypress/{integration/rails_examples/other_spec.js → e2e/rails_examples/other.cy.js} +1 -1
  22. data/lib/generators/cypress_on_rails/templates/spec/cypress/{integration/rails_examples/using_factory_bot_spec.js → e2e/rails_examples/using_factory_bot.cy.js} +1 -1
  23. data/lib/generators/cypress_on_rails/templates/spec/cypress/{integration/rails_examples/using_fixtures_spec.js → e2e/rails_examples/using_fixtures.cy.js} +1 -1
  24. data/lib/generators/cypress_on_rails/templates/spec/cypress/{integration/rails_examples/using_scenarios_spec.js → e2e/rails_examples/using_scenarios.cy.js} +1 -1
  25. data/lib/generators/cypress_on_rails/templates/spec/cypress/e2e/rails_examples/using_vcr.cy.js +24 -0
  26. data/lib/generators/cypress_on_rails/templates/spec/cypress/support/{index.js → index.js.erb} +1 -0
  27. data/lib/generators/cypress_on_rails/templates/spec/cypress/support/on-rails.js +9 -7
  28. data/lib/generators/cypress_on_rails/templates/spec/cypress.config.js +9 -0
  29. data/lib/generators/cypress_on_rails/templates/spec/{cypress → e2e}/app_commands/clean.rb +8 -0
  30. data/lib/generators/cypress_on_rails/templates/spec/{cypress → e2e}/app_commands/log_fail.rb +2 -0
  31. data/lib/generators/cypress_on_rails/templates/spec/{cypress/cypress_helper.rb → e2e/e2e_helper.rb.erb} +6 -1
  32. data/lib/generators/cypress_on_rails/templates/spec/playwright/e2e/rails_examples/using_scenarios.spec.js +12 -0
  33. data/lib/generators/cypress_on_rails/templates/spec/playwright/support/index.js.erb +21 -0
  34. data/lib/generators/cypress_on_rails/templates/spec/playwright/support/on-rails.js +37 -0
  35. data/lib/generators/cypress_on_rails/templates/spec/playwright.config.js +79 -0
  36. data/lib/generators/cypress_on_rails/update_generator.rb +14 -3
  37. data/plugin/.gitignore +1 -0
  38. data/plugin/cypress/plugins/index.js +4 -0
  39. data/plugin/package.json +31 -0
  40. data/plugin/support/index.js +37 -0
  41. data/spec/cypress_on_rails/command_executor_spec.rb +1 -1
  42. data/spec/cypress_on_rails/configuration_spec.rb +6 -3
  43. data/spec/cypress_on_rails/middleware_spec.rb +24 -22
  44. data/spec/cypress_on_rails/smart_factory_wrapper_spec.rb +33 -1
  45. data/spec/cypress_on_rails/vcr_middleware_spec.rb +119 -0
  46. data/specs_e2e/cypress.config.js +10 -0
  47. data/specs_e2e/playwright.config.js +79 -0
  48. data/{spec/integrations → specs_e2e}/rails_3_2/.gitignore +1 -1
  49. data/specs_e2e/rails_3_2/.ruby_version +1 -0
  50. data/{spec/integrations → specs_e2e}/rails_3_2/Gemfile +1 -1
  51. data/{spec/integrations → specs_e2e}/rails_3_2/test.sh +17 -11
  52. data/{spec/integrations → specs_e2e}/rails_4_2/.gitignore +3 -2
  53. data/{spec/integrations → specs_e2e}/rails_4_2/Gemfile +3 -1
  54. data/specs_e2e/rails_4_2/app/controllers/using_vcr_controller.rb +10 -0
  55. data/{spec/integrations → specs_e2e}/rails_4_2/app/models/post.rb +3 -1
  56. data/specs_e2e/rails_4_2/app/views/using_vcr/index.html.erb +6 -0
  57. data/specs_e2e/rails_4_2/app/views/using_vcr/record_cats.html.erb +7 -0
  58. data/{spec/integrations → specs_e2e}/rails_4_2/config/routes.rb +5 -0
  59. data/specs_e2e/rails_4_2/package.json +10 -0
  60. data/specs_e2e/rails_4_2/test.sh +44 -0
  61. data/{spec/integrations → specs_e2e}/rails_5_2/.gitignore +1 -1
  62. data/{spec/integrations → specs_e2e}/rails_5_2/Gemfile +1 -1
  63. data/specs_e2e/rails_5_2/app/assets/javascripts/posts.js +2 -0
  64. data/specs_e2e/rails_5_2/app/assets/stylesheets/posts.css +4 -0
  65. data/specs_e2e/rails_5_2/test.sh +48 -0
  66. metadata +190 -177
  67. data/.travis.yml +0 -39
  68. data/lib/generators/cypress_on_rails/templates/spec/cypress/fixtures/example.json +0 -5
  69. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/actions.spec.js +0 -272
  70. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/aliasing.spec.js +0 -42
  71. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/assertions.spec.js +0 -63
  72. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/connectors.spec.js +0 -55
  73. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/cookies.spec.js +0 -78
  74. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/cypress_api.spec.js +0 -211
  75. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/files.spec.js +0 -86
  76. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/local_storage.spec.js +0 -52
  77. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/location.spec.js +0 -32
  78. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/misc.spec.js +0 -68
  79. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/navigation.spec.js +0 -54
  80. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/network_requests.spec.js +0 -108
  81. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/querying.spec.js +0 -65
  82. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/spies_stubs_clocks.spec.js +0 -62
  83. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/traversal.spec.js +0 -121
  84. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/utilities.spec.js +0 -89
  85. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/viewport.spec.js +0 -59
  86. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/waiting.spec.js +0 -34
  87. data/lib/generators/cypress_on_rails/templates/spec/cypress/integration/examples/window.spec.js +0 -22
  88. data/lib/generators/cypress_on_rails/templates/spec/cypress.json +0 -4
  89. data/spec/integrations/cypress.json +0 -5
  90. data/spec/integrations/rails_4_2/test.sh +0 -38
  91. data/spec/integrations/rails_5_2/test.sh +0 -41
  92. data/spec/integrations/rails_5_2/tmp/.keep +0 -0
  93. data/spec/integrations/rails_5_2/vendor/.keep +0 -0
  94. /data/lib/generators/cypress_on_rails/templates/spec/{cypress → e2e}/app_commands/activerecord_fixtures.rb +0 -0
  95. /data/lib/generators/cypress_on_rails/templates/spec/{cypress → e2e}/app_commands/eval.rb +0 -0
  96. /data/lib/generators/cypress_on_rails/templates/spec/{cypress → e2e}/app_commands/factory_bot.rb +0 -0
  97. /data/lib/generators/cypress_on_rails/templates/spec/{cypress → e2e}/app_commands/scenarios/basic.rb +0 -0
  98. /data/spec/cypress_on_rails/command_executor/{cypress_helper.rb → e2e_helper.rb} +0 -0
  99. /data/{spec/integrations → specs_e2e}/rails_3_2/README.rdoc +0 -0
  100. /data/{spec/integrations → specs_e2e}/rails_3_2/Rakefile +0 -0
  101. /data/{spec/integrations → specs_e2e}/rails_3_2/app/assets/stylesheets/application.css +0 -0
  102. /data/{spec/integrations → specs_e2e}/rails_3_2/app/controllers/application_controller.rb +0 -0
  103. /data/{spec/integrations → specs_e2e}/rails_3_2/app/controllers/welcome_controller.rb +0 -0
  104. /data/{spec/integrations → specs_e2e}/rails_3_2/app/helpers/application_helper.rb +0 -0
  105. /data/{spec/integrations → specs_e2e}/rails_3_2/app/models/post.rb +0 -0
  106. /data/{spec/integrations → specs_e2e}/rails_3_2/app/views/layouts/application.html.erb +0 -0
  107. /data/{spec/integrations → specs_e2e}/rails_3_2/app/views/welcome/index.html.erb +0 -0
  108. /data/{spec/integrations → specs_e2e}/rails_3_2/bin/rails +0 -0
  109. /data/{spec/integrations → specs_e2e}/rails_3_2/config/application.rb +0 -0
  110. /data/{spec/integrations → specs_e2e}/rails_3_2/config/boot.rb +0 -0
  111. /data/{spec/integrations → specs_e2e}/rails_3_2/config/environment.rb +0 -0
  112. /data/{spec/integrations → specs_e2e}/rails_3_2/config/environments/development.rb +0 -0
  113. /data/{spec/integrations → specs_e2e}/rails_3_2/config/environments/production.rb +0 -0
  114. /data/{spec/integrations → specs_e2e}/rails_3_2/config/environments/test.rb +0 -0
  115. /data/{spec/integrations → specs_e2e}/rails_3_2/config/initializers/backtrace_silencers.rb +0 -0
  116. /data/{spec/integrations → specs_e2e}/rails_3_2/config/initializers/inflections.rb +0 -0
  117. /data/{spec/integrations → specs_e2e}/rails_3_2/config/initializers/mime_types.rb +0 -0
  118. /data/{spec/integrations → specs_e2e}/rails_3_2/config/initializers/secret_token.rb +0 -0
  119. /data/{spec/integrations → specs_e2e}/rails_3_2/config/initializers/session_store.rb +0 -0
  120. /data/{spec/integrations → specs_e2e}/rails_3_2/config/initializers/wrap_parameters.rb +0 -0
  121. /data/{spec/integrations → specs_e2e}/rails_3_2/config/locales/en.yml +0 -0
  122. /data/{spec/integrations → specs_e2e}/rails_3_2/config/routes.rb +0 -0
  123. /data/{spec/integrations → specs_e2e}/rails_3_2/config.ru +0 -0
  124. /data/{spec/integrations → specs_e2e}/rails_3_2/log/.keep +0 -0
  125. /data/{spec/integrations → specs_e2e}/rails_3_2/public/404.html +0 -0
  126. /data/{spec/integrations → specs_e2e}/rails_3_2/public/422.html +0 -0
  127. /data/{spec/integrations → specs_e2e}/rails_3_2/public/500.html +0 -0
  128. /data/{spec/integrations → specs_e2e}/rails_3_2/public/favicon.ico +0 -0
  129. /data/{spec/integrations → specs_e2e}/rails_3_2/public/robots.txt +0 -0
  130. /data/{spec/integrations → specs_e2e}/rails_3_2/tmp/.keep +0 -0
  131. /data/{spec/integrations → specs_e2e}/rails_3_2/vendor/.gitkeep +0 -0
  132. /data/{spec/integrations → specs_e2e}/rails_4_2/README.rdoc +0 -0
  133. /data/{spec/integrations → specs_e2e}/rails_4_2/Rakefile +0 -0
  134. /data/{spec/integrations/rails_5_2/app/assets/javascripts/posts.js → specs_e2e/rails_4_2/app/assets/javascripts/using_vcr.js} +0 -0
  135. /data/{spec/integrations/rails_5_2/app/assets/stylesheets/posts.css → specs_e2e/rails_4_2/app/assets/stylesheets/using_vcr.css} +0 -0
  136. /data/{spec/integrations → specs_e2e}/rails_4_2/app/controllers/application_controller.rb +0 -0
  137. /data/{spec/integrations → specs_e2e}/rails_4_2/app/controllers/welcome_controller.rb +0 -0
  138. /data/{spec/integrations → specs_e2e}/rails_4_2/app/views/layouts/application.html.erb +0 -0
  139. /data/{spec/integrations → specs_e2e}/rails_4_2/app/views/welcome/index.html.erb +0 -0
  140. /data/{spec/integrations → specs_e2e}/rails_4_2/bin/bundle +0 -0
  141. /data/{spec/integrations → specs_e2e}/rails_4_2/bin/rails +0 -0
  142. /data/{spec/integrations → specs_e2e}/rails_4_2/bin/rake +0 -0
  143. /data/{spec/integrations → specs_e2e}/rails_4_2/bin/setup +0 -0
  144. /data/{spec/integrations → specs_e2e}/rails_4_2/config/application.rb +0 -0
  145. /data/{spec/integrations → specs_e2e}/rails_4_2/config/boot.rb +0 -0
  146. /data/{spec/integrations → specs_e2e}/rails_4_2/config/environment.rb +0 -0
  147. /data/{spec/integrations → specs_e2e}/rails_4_2/config/environments/development.rb +0 -0
  148. /data/{spec/integrations → specs_e2e}/rails_4_2/config/environments/production.rb +0 -0
  149. /data/{spec/integrations → specs_e2e}/rails_4_2/config/environments/test.rb +0 -0
  150. /data/{spec/integrations → specs_e2e}/rails_4_2/config/initializers/backtrace_silencers.rb +0 -0
  151. /data/{spec/integrations → specs_e2e}/rails_4_2/config/initializers/cookies_serializer.rb +0 -0
  152. /data/{spec/integrations → specs_e2e}/rails_4_2/config/initializers/filter_parameter_logging.rb +0 -0
  153. /data/{spec/integrations → specs_e2e}/rails_4_2/config/initializers/inflections.rb +0 -0
  154. /data/{spec/integrations → specs_e2e}/rails_4_2/config/initializers/mime_types.rb +0 -0
  155. /data/{spec/integrations → specs_e2e}/rails_4_2/config/initializers/session_store.rb +0 -0
  156. /data/{spec/integrations → specs_e2e}/rails_4_2/config/initializers/to_time_preserves_timezone.rb +0 -0
  157. /data/{spec/integrations → specs_e2e}/rails_4_2/config/initializers/wrap_parameters.rb +0 -0
  158. /data/{spec/integrations → specs_e2e}/rails_4_2/config/locales/en.yml +0 -0
  159. /data/{spec/integrations → specs_e2e}/rails_4_2/config/secrets.yml +0 -0
  160. /data/{spec/integrations → specs_e2e}/rails_4_2/config.ru +0 -0
  161. /data/{spec/integrations → specs_e2e}/rails_4_2/public/404.html +0 -0
  162. /data/{spec/integrations → specs_e2e}/rails_4_2/public/422.html +0 -0
  163. /data/{spec/integrations → specs_e2e}/rails_4_2/public/500.html +0 -0
  164. /data/{spec/integrations → specs_e2e}/rails_4_2/public/favicon.ico +0 -0
  165. /data/{spec/integrations → specs_e2e}/rails_4_2/public/robots.txt +0 -0
  166. /data/{spec/integrations/rails_4_2/log → specs_e2e/rails_4_2/spec}/.keep +0 -0
  167. /data/{spec/integrations/rails_4_2/spec → specs_e2e/rails_4_2/vendor}/.keep +0 -0
  168. /data/{spec/integrations → specs_e2e}/rails_5_2/README.md +0 -0
  169. /data/{spec/integrations → specs_e2e}/rails_5_2/Rakefile +0 -0
  170. /data/{spec/integrations → specs_e2e}/rails_5_2/app/assets/stylesheets/scaffold.css +0 -0
  171. /data/{spec/integrations → specs_e2e}/rails_5_2/app/controllers/application_controller.rb +0 -0
  172. /data/{spec/integrations → specs_e2e}/rails_5_2/app/controllers/posts_controller.rb +0 -0
  173. /data/{spec/integrations → specs_e2e}/rails_5_2/app/helpers/posts_helper.rb +0 -0
  174. /data/{spec/integrations → specs_e2e}/rails_5_2/app/jobs/application_job.rb +0 -0
  175. /data/{spec/integrations → specs_e2e}/rails_5_2/app/models/application_record.rb +0 -0
  176. /data/{spec/integrations → specs_e2e}/rails_5_2/app/models/post.rb +0 -0
  177. /data/{spec/integrations → specs_e2e}/rails_5_2/app/views/layouts/application.html.erb +0 -0
  178. /data/{spec/integrations → specs_e2e}/rails_5_2/app/views/posts/_form.html.erb +0 -0
  179. /data/{spec/integrations → specs_e2e}/rails_5_2/app/views/posts/edit.html.erb +0 -0
  180. /data/{spec/integrations → specs_e2e}/rails_5_2/app/views/posts/index.html.erb +0 -0
  181. /data/{spec/integrations → specs_e2e}/rails_5_2/app/views/posts/new.html.erb +0 -0
  182. /data/{spec/integrations → specs_e2e}/rails_5_2/app/views/posts/show.html.erb +0 -0
  183. /data/{spec/integrations → specs_e2e}/rails_5_2/app/views/welcome/index.html.erb +0 -0
  184. /data/{spec/integrations → specs_e2e}/rails_5_2/bin/bundle +0 -0
  185. /data/{spec/integrations → specs_e2e}/rails_5_2/bin/rails +0 -0
  186. /data/{spec/integrations → specs_e2e}/rails_5_2/bin/rake +0 -0
  187. /data/{spec/integrations → specs_e2e}/rails_5_2/bin/setup +0 -0
  188. /data/{spec/integrations → specs_e2e}/rails_5_2/bin/update +0 -0
  189. /data/{spec/integrations → specs_e2e}/rails_5_2/config/application.rb +0 -0
  190. /data/{spec/integrations → specs_e2e}/rails_5_2/config/boot.rb +0 -0
  191. /data/{spec/integrations → specs_e2e}/rails_5_2/config/credentials.yml.enc +0 -0
  192. /data/{spec/integrations → specs_e2e}/rails_5_2/config/database.yml +0 -0
  193. /data/{spec/integrations → specs_e2e}/rails_5_2/config/environment.rb +0 -0
  194. /data/{spec/integrations → specs_e2e}/rails_5_2/config/environments/development.rb +0 -0
  195. /data/{spec/integrations → specs_e2e}/rails_5_2/config/environments/production.rb +0 -0
  196. /data/{spec/integrations → specs_e2e}/rails_5_2/config/environments/test.rb +0 -0
  197. /data/{spec/integrations → specs_e2e}/rails_5_2/config/initializers/application_controller_renderer.rb +0 -0
  198. /data/{spec/integrations → specs_e2e}/rails_5_2/config/initializers/backtrace_silencers.rb +0 -0
  199. /data/{spec/integrations → specs_e2e}/rails_5_2/config/initializers/content_security_policy.rb +0 -0
  200. /data/{spec/integrations → specs_e2e}/rails_5_2/config/initializers/cookies_serializer.rb +0 -0
  201. /data/{spec/integrations → specs_e2e}/rails_5_2/config/initializers/filter_parameter_logging.rb +0 -0
  202. /data/{spec/integrations → specs_e2e}/rails_5_2/config/initializers/inflections.rb +0 -0
  203. /data/{spec/integrations → specs_e2e}/rails_5_2/config/initializers/mime_types.rb +0 -0
  204. /data/{spec/integrations → specs_e2e}/rails_5_2/config/initializers/wrap_parameters.rb +0 -0
  205. /data/{spec/integrations → specs_e2e}/rails_5_2/config/locales/en.yml +0 -0
  206. /data/{spec/integrations → specs_e2e}/rails_5_2/config/master.key +0 -0
  207. /data/{spec/integrations → specs_e2e}/rails_5_2/config/routes.rb +0 -0
  208. /data/{spec/integrations → specs_e2e}/rails_5_2/config.ru +0 -0
  209. /data/{spec/integrations → specs_e2e}/rails_5_2/db/migrate/20180621085832_create_posts.rb +0 -0
  210. /data/{spec/integrations → specs_e2e}/rails_5_2/public/404.html +0 -0
  211. /data/{spec/integrations → specs_e2e}/rails_5_2/public/422.html +0 -0
  212. /data/{spec/integrations → specs_e2e}/rails_5_2/public/500.html +0 -0
  213. /data/{spec/integrations → specs_e2e}/rails_5_2/public/apple-touch-icon-precomposed.png +0 -0
  214. /data/{spec/integrations → specs_e2e}/rails_5_2/public/apple-touch-icon.png +0 -0
  215. /data/{spec/integrations → specs_e2e}/rails_5_2/public/favicon.ico +0 -0
  216. /data/{spec/integrations → specs_e2e}/rails_5_2/public/robots.txt +0 -0
  217. /data/{spec/integrations → specs_e2e}/rails_5_2/test/controllers/posts_controller_test.rb +0 -0
  218. /data/{spec/integrations → specs_e2e}/rails_5_2/test/cypress_fixtures/posts.yml +0 -0
  219. /data/{spec/integrations → specs_e2e}/rails_5_2/test/fixtures/posts.yml +0 -0
  220. /data/{spec/integrations → specs_e2e}/rails_5_2/test/models/post_test.rb +0 -0
  221. /data/{spec/integrations/rails_4_2 → specs_e2e/rails_5_2}/vendor/.keep +0 -0
  222. /data/{spec/integrations/rails_5_2/log/.keep → tmp/pids/.gitkeep} +0 -0
@@ -1,6 +1,6 @@
1
1
  # Example for Authenticating a User
2
2
 
3
- in routes.rb
3
+ In `config/routes.rb`:
4
4
  ```rb
5
5
  Rails.application.routes.draw do
6
6
  # ...... your other routes
@@ -12,7 +12,7 @@ Rails.application.routes.draw do
12
12
  end
13
13
  ```
14
14
 
15
- app/controllers/cypress_controller.rb
15
+ `app/controllers/cypress_controller.rb`:
16
16
  ```rb
17
17
  class CypressController < ApplicationController
18
18
  skip_before_action :verify_authenticity_token
@@ -29,21 +29,23 @@ class CypressController < ApplicationController
29
29
  end
30
30
  ```
31
31
 
32
- in cypress/support/on-rails.js
32
+ In `cypress/support/on-rails.js`:
33
33
  ```js
34
- Cypress.Commands.add("forceLogin", (details) => {
35
- if(!details)
34
+ Cypress.Commands.add('forceLogin', (details) => {
35
+ if (!details) {
36
36
  details = {}
37
+ }
37
38
 
38
- if(!details.redirect_to)
39
+ if (!details.redirect_to) {
39
40
  details.redirect_to = '/'
41
+ }
40
42
 
41
- cy.visit("__cypress__/forceLogin",
42
- { method: "POST", body: { email: details.email, redirect_to: details.redirect_to } })
43
- });
43
+ cy.visit('__cypress__/forceLogin',
44
+ { method: 'POST', body: { email: details.email, redirect_to: details.redirect_to } })
45
+ })
44
46
  ```
45
47
 
46
- examples of usage in cypress specs
48
+ Examples of usage in Cypress specs:
47
49
  ```js
48
50
  cy.forceLogin()
49
51
  cy.forceLogin({redirect_to: '/profile'})
@@ -0,0 +1,109 @@
1
+ # Setting up associations with the correct data
2
+
3
+ You cannot access associations directly from Cypress like you can do with Ruby tests.
4
+ So setting up associations has to be done differently from within Cypress.
5
+
6
+ There are a few ways you can setup associations with the correct data using Cypress and FactoryBot.
7
+ 1. Setting the foreign keys
8
+ 2. Using transient attributes
9
+ 3. Using Nested Attributes
10
+ 4. Combination of the above depending on your situation
11
+
12
+ Assuming you have the following models
13
+
14
+ ```rb
15
+ class Post < ApplicationRecord
16
+ belongs_to :author
17
+ accepts_nested_attributes_for :author
18
+ end
19
+
20
+ class Author < ApplicationRecord
21
+ has_many :posts
22
+ accepts_nested_attributes_for :posts
23
+ end
24
+ ```
25
+
26
+ You can do the following:
27
+
28
+ ## 1. Setting the foreign keys
29
+
30
+ `factories.rb`:
31
+ ```rb
32
+ FactoryBot.define do
33
+ factory :author do
34
+ name { 'Taylor' }
35
+ end
36
+
37
+ factory :post do
38
+ title { 'Cypress on Rails is Awesome' }
39
+ author_id { create(:author).id }
40
+ end
41
+ end
42
+ ```
43
+
44
+ then in Cypress
45
+ ```js
46
+ // example with overriding the defaults
47
+ cy.appFactories([['create', 'author', { name: 'James' }]]).then((records) => {
48
+ cy.appFactories([['create', 'post', { title: 'Cypress is cool', author_id: records[0].id }]])
49
+ })
50
+
51
+ // example without overriding anything
52
+ cy.appFactories([['create', 'author']]).then((records) => {
53
+ cy.appFactories([['create', 'post', { author_id: records[0].id }]])
54
+ })
55
+ ```
56
+
57
+ ## 2. Using transient attributes
58
+
59
+ ```rb
60
+ FactoryBot.define do
61
+ factory :author do
62
+ name { 'Taylor' }
63
+ end
64
+
65
+ factory :post do
66
+ transient do
67
+ author_name { 'Taylor' }
68
+ end
69
+ title { 'Cypress on Rails is Awesome' }
70
+ author { create(:author, name: author_name ) }
71
+ end
72
+ end
73
+ ```
74
+
75
+ then in Cypress
76
+ ```js
77
+ // example with overriding the defaults
78
+ cy.appFactories([['create', 'post', { title: 'Cypress is cool', author_name: 'James' }]])
79
+
80
+ // example without overriding
81
+ cy.appFactories([['create', 'post']])
82
+ ```
83
+
84
+ ## 3. Using Nested Attributes
85
+
86
+ ```rb
87
+ FactoryBot.define do
88
+ factory :author do
89
+ name { 'Taylor' }
90
+ end
91
+
92
+ factory :post do
93
+ title { 'Cypress on Rails is Awesome' }
94
+ author_attributes { { name: 'Taylor' } }
95
+ end
96
+ end
97
+ ```
98
+
99
+ then in Cypress
100
+ ```js
101
+ // example with overriding the defaults
102
+ cy.appFactories([['create', 'post', { title: 'Cypress is cool', author_attributes: { name: 'James' } }]])
103
+
104
+ // example without overriding
105
+ cy.appFactories([['create', 'post']])
106
+
107
+ // example of creating author with multiple posts
108
+ cy.appFactories([['create', 'author', { name: 'James', posts_attributes: [{ name: 'Cypress is cool' }, {name: 'Rails is awesome' }] }]])
109
+ ```
@@ -3,5 +3,5 @@ require 'cypress_on_rails/configuration'
3
3
  require_relative './cypress_on_rails/railtie' if defined?(Rails)
4
4
 
5
5
  # maintain backward compatibility
6
- CypressDev = CypressOnRails
7
- Cypress = CypressDev
6
+ CypressDev = CypressOnRails unless defined?(CypressDev)
7
+ Cypress = CypressDev unless defined?(Cypress)
@@ -4,7 +4,7 @@ module CypressOnRails
4
4
  # loads and evals the command files
5
5
  class CommandExecutor
6
6
  def self.perform(file,command_options = nil)
7
- load_cypress_helper
7
+ load_e2e_helper
8
8
  file_data = File.read(file)
9
9
  eval file_data, binding, file
10
10
  rescue => e
@@ -13,12 +13,16 @@ module CypressOnRails
13
13
  raise e
14
14
  end
15
15
 
16
- def self.load_cypress_helper
17
- cypress_helper_file = "#{configuration.cypress_folder}/cypress_helper"
18
- if File.exist?("#{cypress_helper_file}.rb")
16
+ def self.load_e2e_helper
17
+ e2e_helper_file = "#{configuration.install_folder}/e2e_helper.rb"
18
+ cypress_helper_file = "#{configuration.install_folder}/cypress_helper.rb"
19
+ if File.exist?(e2e_helper_file)
20
+ Kernel.require e2e_helper_file
21
+ elsif File.exist?(cypress_helper_file)
19
22
  Kernel.require cypress_helper_file
23
+ warn "cypress_helper.rb is deprecated, please rename the file to e2e_helper.rb"
20
24
  else
21
- logger.warn "could not find #{cypress_helper_file}.rb"
25
+ logger.warn "could not find #{e2e_helper_file} nor #{cypress_helper_file}"
22
26
  end
23
27
  end
24
28
 
@@ -2,19 +2,34 @@ require 'logger'
2
2
 
3
3
  module CypressOnRails
4
4
  class Configuration
5
- attr_accessor :cypress_folder
5
+ attr_accessor :api_prefix
6
+ attr_accessor :install_folder
6
7
  attr_accessor :use_middleware
8
+ attr_accessor :use_vcr_middleware
7
9
  attr_accessor :logger
8
10
 
11
+ # Attributes for backwards compatibility
12
+ def cypress_folder
13
+ warn "cypress_folder is deprecated, please use install_folder"
14
+ install_folder
15
+ end
16
+ def cypress_folder=(v)
17
+ warn "cypress_folder= is deprecated, please use install_folder"
18
+ self.install_folder = v
19
+ end
20
+
9
21
  def initialize
10
22
  reset
11
23
  end
12
24
 
13
25
  alias :use_middleware? :use_middleware
26
+ alias :use_vcr_middleware? :use_vcr_middleware
14
27
 
15
28
  def reset
16
- self.cypress_folder = 'spec/cypress'
29
+ self.api_prefix = ''
30
+ self.install_folder = 'spec/e2e'
17
31
  self.use_middleware = true
32
+ self.use_vcr_middleware = false
18
33
  self.logger = Logger.new(STDOUT)
19
34
  end
20
35
 
@@ -1,11 +1,13 @@
1
1
  require 'json'
2
2
  require 'rack'
3
- require 'cypress_on_rails/configuration'
3
+ require 'cypress_on_rails/middleware_config'
4
4
  require 'cypress_on_rails/command_executor'
5
5
 
6
6
  module CypressOnRails
7
- # Middleware to handle cypress commands and eval
7
+ # Middleware to handle testing framework commands and eval
8
8
  class Middleware
9
+ include MiddlewareConfig
10
+
9
11
  def initialize(app, command_executor = CommandExecutor, file = ::File)
10
12
  @app = app
11
13
  @command_executor = command_executor
@@ -14,7 +16,10 @@ module CypressOnRails
14
16
 
15
17
  def call(env)
16
18
  request = Rack::Request.new(env)
17
- if request.path.start_with?('/__cypress__/command')
19
+ if request.path.start_with?("#{configuration.api_prefix}/__e2e__/command")
20
+ configuration.tagged_logged { handle_command(request) }
21
+ elsif request.path.start_with?("#{configuration.api_prefix}/__cypress__/command")
22
+ warn "/__cypress__/command is deprecated. Please use the install generator to use /__e2e__/command instead."
18
23
  configuration.tagged_logged { handle_command(request) }
19
24
  else
20
25
  @app.call(env)
@@ -23,15 +28,7 @@ module CypressOnRails
23
28
 
24
29
  private
25
30
 
26
- def configuration
27
- CypressOnRails.configuration
28
- end
29
-
30
- def logger
31
- configuration.logger
32
- end
33
-
34
- Command = Struct.new(:name, :options, :cypress_folder) do
31
+ Command = Struct.new(:name, :options, :install_folder) do
35
32
  # @return [Array<Cypress::Middleware::Command>]
36
33
  def self.from_body(body, configuration)
37
34
  if body.is_a?(Array)
@@ -40,12 +37,12 @@ module CypressOnRails
40
37
  command_params = [body]
41
38
  end
42
39
  command_params.map do |params|
43
- new(params.fetch('name'), params['options'], configuration.cypress_folder)
40
+ new(params.fetch('name'), params['options'], configuration.install_folder)
44
41
  end
45
42
  end
46
43
 
47
44
  def file_path
48
- "#{cypress_folder}/app_commands/#{name}.rb"
45
+ "#{install_folder}/app_commands/#{name}.rb"
49
46
  end
50
47
  end
51
48
 
@@ -53,7 +50,7 @@ module CypressOnRails
53
50
  body = JSON.parse(req.body.read)
54
51
  logger.info "handle_command: #{body}"
55
52
  commands = Command.from_body(body, configuration)
56
- missing_command = commands.find {|command| !@file.exists?(command.file_path) }
53
+ missing_command = commands.find {|command| !@file.exist?(command.file_path) }
57
54
 
58
55
  if missing_command.nil?
59
56
  begin
@@ -65,13 +62,15 @@ module CypressOnRails
65
62
  output = {"message" => "Cannot convert to json"}.to_json
66
63
  end
67
64
 
65
+ logger.debug "output: #{output}"
68
66
  [201, {'Content-Type' => 'application/json'}, [output]]
69
67
  rescue => e
70
68
  output = {"message" => e.message, "class" => e.class.to_s}.to_json
71
69
  [500, {'Content-Type' => 'application/json'}, [output]]
72
70
  end
73
71
  else
74
- [404, {}, ["could not find command file: #{missing_command.file_path}"]]
72
+ output = {"message" => "could not find command file: #{missing_command.file_path}"}.to_json
73
+ [404, {'Content-Type' => 'application/json'}, [output]]
75
74
  end
76
75
  end
77
76
  end
@@ -0,0 +1,17 @@
1
+ require 'json'
2
+ require 'rack'
3
+ require 'cypress_on_rails/configuration'
4
+
5
+ module CypressOnRails
6
+ module MiddlewareConfig
7
+ protected
8
+
9
+ def configuration
10
+ CypressOnRails.configuration
11
+ end
12
+
13
+ def logger
14
+ configuration.logger
15
+ end
16
+ end
17
+ end
@@ -1,13 +1,17 @@
1
1
  require 'rails/railtie'
2
2
  require 'cypress_on_rails/configuration'
3
- require 'cypress_on_rails/middleware'
4
3
 
5
4
  module CypressOnRails
6
5
  class Railtie < Rails::Railtie
7
6
  initializer :setup_cypress_middleware, after: :load_config_initializers do |app|
8
7
  if CypressOnRails.configuration.use_middleware?
8
+ require 'cypress_on_rails/middleware'
9
9
  app.middleware.use Middleware
10
10
  end
11
+ if CypressOnRails.configuration.use_vcr_middleware?
12
+ require 'cypress_on_rails/vcr_middleware'
13
+ app.middleware.use VCRMiddleware
14
+ end
11
15
  end
12
16
  end
13
17
  end
@@ -19,6 +19,18 @@ module CypressOnRails
19
19
  instance.create_list(*args)
20
20
  end
21
21
 
22
+ def self.build(*args)
23
+ instance.build(*args)
24
+ end
25
+
26
+ def self.build_list(*args)
27
+ instance.build_list(*args)
28
+ end
29
+
30
+ def self.reload
31
+ instance.reload
32
+ end
33
+
22
34
  # @return [Array]
23
35
  attr_accessor :factory
24
36
  attr_accessor :always_reload
@@ -36,7 +48,7 @@ module CypressOnRails
36
48
  end
37
49
 
38
50
  def create(*options)
39
- load_files
51
+ auto_reload
40
52
  factory_name = options.shift
41
53
  if options.last.is_a?(Hash)
42
54
  args = options.pop
@@ -47,10 +59,36 @@ module CypressOnRails
47
59
  end
48
60
 
49
61
  def create_list(*args)
50
- load_files
62
+ auto_reload
51
63
  factory.create_list(*args)
52
64
  end
53
65
 
66
+ def build(*options)
67
+ auto_reload
68
+ factory_name = options.shift
69
+ if options.last.is_a?(Hash)
70
+ args = options.pop
71
+ else
72
+ args = {}
73
+ end
74
+ factory.build(factory_name, *options.map(&:to_sym), args.symbolize_keys)
75
+ end
76
+
77
+ def build_list(*args)
78
+ auto_reload
79
+ factory.build_list(*args)
80
+ end
81
+
82
+ def reload
83
+ @latest_mtime = current_latest_mtime
84
+ logger.info 'Loading Factories'
85
+ factory.reload
86
+ files.each do |file|
87
+ logger.debug "-- Loading: #{file}"
88
+ @kernel.load(file)
89
+ end
90
+ end
91
+
54
92
  private
55
93
 
56
94
  # @param [String,Array] arg
@@ -68,20 +106,17 @@ module CypressOnRails
68
106
  CypressOnRails.configuration.logger
69
107
  end
70
108
 
71
- def load_files
72
- current_latest_mtime = files.map{|file| @file_system.mtime(file) }.max
73
- return unless should_reload?(current_latest_mtime)
74
- logger.info 'Loading Factories'
75
- @latest_mtime = current_latest_mtime
76
- factory.reload
77
- files.each do |file|
78
- logger.debug "-- Loading: #{file}"
79
- @kernel.load(file)
80
- end
109
+ def current_latest_mtime
110
+ files.map{|file| @file_system.mtime(file) }.max
111
+ end
112
+
113
+ def auto_reload
114
+ return unless should_reload?
115
+ reload
81
116
  end
82
117
 
83
- def should_reload?(current_latest_mtime)
118
+ def should_reload?
84
119
  @always_reload || @latest_mtime.nil? || @latest_mtime < current_latest_mtime
85
120
  end
86
121
  end
87
- end
122
+ end
@@ -0,0 +1,73 @@
1
+ require 'json'
2
+ require 'rack'
3
+ require 'cypress_on_rails/middleware_config'
4
+
5
+ module CypressOnRails
6
+ # Middleware to handle vcr
7
+ class VCRMiddleware
8
+ include MiddlewareConfig
9
+
10
+ def initialize(app, vcr = nil)
11
+ @app = app
12
+ @vcr = vcr
13
+ @first_call = false
14
+ end
15
+
16
+ def call(env)
17
+ request = Rack::Request.new(env)
18
+ if request.path.start_with?('/__e2e__/vcr/insert')
19
+ configuration.tagged_logged { handle_insert(request) }
20
+ elsif request.path.start_with?('/__e2e__/vcr/eject')
21
+ configuration.tagged_logged { handle_eject }
22
+ else
23
+ do_first_call unless @first_call
24
+ @app.call(env)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def handle_insert(req)
31
+ WebMock.enable! if defined?(WebMock)
32
+ vcr.turn_on!
33
+ body = JSON.parse(req.body.read)
34
+ logger.info "vcr insert cassette: #{body}"
35
+ cassette_name = body[0]
36
+ options = (body[1] || {}).symbolize_keys
37
+ options[:record] = options[:record].to_sym if options[:record]
38
+ options[:match_requests_on] = options[:match_requests_on].map(&:to_sym) if options[:match_requests_on]
39
+ options[:serialize_with] = options[:serialize_with].to_sym if options[:serialize_with]
40
+ options[:persist_with] = options[:persist_with].to_sym if options[:persist_with]
41
+ vcr.insert_cassette(cassette_name, options)
42
+ [201, {'Content-Type' => 'application/json'}, [{'message': 'OK'}.to_json]]
43
+ rescue LoadError, ArgumentError => e
44
+ [501, {'Content-Type' => 'application/json'}, [{'message': e.message}.to_json]]
45
+ end
46
+
47
+ def handle_eject
48
+ logger.info "vcr eject cassette"
49
+ vcr.eject_cassette
50
+ do_first_call
51
+ [201, {'Content-Type' => 'application/json'}, [{'message': 'OK'}.to_json]]
52
+ rescue LoadError, ArgumentError => e
53
+ [501, {'Content-Type' => 'application/json'}, [{'message': e.message}.to_json]]
54
+ end
55
+
56
+ def vcr
57
+ return @vcr if @vcr
58
+ require 'vcr'
59
+ VCR.configure do |config|
60
+ config.cassette_library_dir = "#{configuration.install_folder}/fixtures/vcr_cassettes"
61
+ end
62
+ @vcr = VCR
63
+ end
64
+
65
+ def do_first_call
66
+ @first_call = true
67
+ vcr.turn_off!
68
+ WebMock.disable! if defined?(WebMock)
69
+ rescue LoadError
70
+ # nop
71
+ end
72
+ end
73
+ end
@@ -1,3 +1,3 @@
1
1
  module CypressOnRails
2
- VERSION = '1.10.1'.freeze
2
+ VERSION = '1.15.1'.freeze
3
3
  end
@@ -1,50 +1,68 @@
1
1
  module CypressOnRails
2
2
  class InstallGenerator < Rails::Generators::Base
3
- class_option :cypress_folder, type: :string, default: 'cypress'
3
+ class_option :api_prefix, type: :string, default: ''
4
+ class_option :install_folder, type: :string, default: 'e2e'
4
5
  class_option :install_cypress, type: :boolean, default: true
5
- class_option :install_cypress_with, type: :string, default: 'yarn'
6
- class_option :install_cypress_examples, type: :boolean, default: false
6
+ class_option :install_playwright, type: :boolean, default: false
7
+ 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
+ class_option :experimental, type: :boolean, default: false
7
11
  source_root File.expand_path('../templates', __FILE__)
8
12
 
9
- def install_cypress
10
- if !Dir.exists?(options.cypress_folder) || Dir["#{options.cypress_folder}/*"].empty?
11
- directories = options.cypress_folder.split('/')
12
- directories.pop
13
- install_dir = "#{Dir.pwd}/#{directories.join('/')}"
14
- command = nil
15
- if options.install_cypress
16
- if options.install_cypress_with == 'yarn'
17
- command = "yarn --cwd=#{install_dir} add cypress --dev"
18
- elsif options.install_cypress_with == 'npm'
19
- command = "cd #{install_dir}; npm install cypress --save-dev"
20
- end
21
- if command
22
- say command
23
- fail 'failed to install cypress' unless system(command)
24
- end
25
- end
26
- if options.install_cypress_examples
27
- directory 'spec/cypress/integration/examples', "#{options.cypress_folder}/integration/examples"
28
- directory 'spec/cypress/fixtures', "#{options.cypress_folder}/fixtures"
29
- end
30
- copy_file "spec/cypress/support/index.js", "#{options.cypress_folder}/support/index.js"
13
+ def install_framework
14
+ directories = options.install_folder.split('/')
15
+ directories.pop
16
+ install_dir = "#{Dir.pwd}/#{directories.join('/')}"
17
+
18
+ command = nil
19
+ packages = []
20
+
21
+ packages << 'cypress' if options.install_cypress
22
+ packages.push('playwright', '@playwright/test') if options.install_playwright
23
+
24
+ if options.install_with == 'yarn'
25
+ command = "yarn --cwd=#{install_dir} add #{packages.join(' ')} --dev"
26
+ elsif options.install_with == 'npm'
27
+ command = "cd #{install_dir}; npm install #{packages.join(' ')} --save-dev"
28
+ end
29
+ if command
30
+ say command
31
+ fail "failed to install #{packages.join(' ')}" unless system(command)
32
+ end
33
+
34
+ if options.install_cypress
35
+ template "spec/cypress/support/index.js.erb", "#{options.cypress_folder}/support/index.js"
31
36
  copy_file "spec/cypress/support/commands.js", "#{options.cypress_folder}/support/commands.js"
32
- copy_file "spec/cypress.json", "#{options.cypress_folder}/../cypress.json"
37
+ copy_file "spec/cypress.config.js", "#{options.cypress_folder}/../cypress.config.js"
38
+ 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"
33
42
  end
34
43
  end
35
44
 
36
45
  def add_initial_files
37
46
  template "config/initializers/cypress_on_rails.rb.erb", "config/initializers/cypress_on_rails.rb"
38
- copy_file "spec/cypress/cypress_helper.rb", "#{options.cypress_folder}/cypress_helper.rb"
39
- copy_file "spec/cypress/support/on-rails.js", "#{options.cypress_folder}/support/on-rails.js"
40
- directory 'spec/cypress/app_commands', "#{options.cypress_folder}/app_commands"
41
- directory 'spec/cypress/integration/rails_examples', "#{options.cypress_folder}/integration/rails_examples"
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"
52
+ 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"
56
+ end
42
57
  end
43
58
 
44
59
  def update_files
45
60
  append_to_file "#{options.cypress_folder}/support/index.js",
46
61
  "\nimport './on-rails'",
47
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:'
48
66
  end
49
67
  end
50
68
  end
@@ -1,9 +1,11 @@
1
1
  if defined?(CypressOnRails)
2
2
  CypressOnRails.configure do |c|
3
- c.cypress_folder = File.expand_path("#{__dir__}/../../<%= options.cypress_folder %>")
3
+ c.api_prefix = "<%= options.api_prefix %>"
4
+ c.install_folder = File.expand_path("#{__dir__}/../../<%= options.install_folder %>")
4
5
  # WARNING!! CypressOnRails can execute arbitrary ruby code
5
6
  # please use with extra caution if enabling on hosted servers or starting your local server on 0.0.0.0
6
7
  c.use_middleware = !Rails.env.production?
8
+ <% unless options.experimental %># <% end %> c.use_vcr_middleware = !Rails.env.production?
7
9
  c.logger = Rails.logger
8
10
  end
9
11
 
@@ -1,6 +1,6 @@
1
1
  describe('More Rails using factory bot examples', function() {
2
2
  beforeEach(() => {
3
- cy.app('clean') // have a look at cypress/app_commands/clean.rb
3
+ cy.app('clean') // have a look at e2e/app_commands/clean.rb
4
4
  })
5
5
 
6
6
  it('using response from factory bot', function() {
@@ -1,6 +1,6 @@
1
1
  describe('Rails Other examples', function() {
2
2
  it('cypress eval', function() {
3
- cy.app('clean') // have a look at cypress/app_commands/clean.rb
3
+ cy.app('clean') // have a look at e2e/app_commands/clean.rb
4
4
  cy.appEval("Post.create(title: 'Hello Eval')")
5
5
 
6
6
  cy.visit('/')
@@ -1,6 +1,6 @@
1
1
  describe('Rails using factory bot examples', function() {
2
2
  beforeEach(() => {
3
- cy.app('clean') // have a look at cypress/app_commands/clean.rb
3
+ cy.app('clean') // have a look at e2e/app_commands/clean.rb
4
4
  })
5
5
 
6
6
  it('using single factory bot', function() {