cypress-on-rails 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -6
  3. data/CHANGELOG.md +4 -0
  4. data/README.md +61 -27
  5. data/lib/cypress_dev/version.rb +1 -1
  6. data/lib/generators/cypress_dev/install_generator.rb +7 -5
  7. data/lib/generators/cypress_dev/templates/spec/cypress/app_commands/activerecord_fixtures.rb +21 -0
  8. data/lib/generators/cypress_dev/templates/spec/cypress/app_commands/clean.rb +1 -0
  9. data/lib/generators/cypress_dev/templates/spec/cypress/app_commands/scenarios/basic.rb +2 -1
  10. data/lib/generators/cypress_dev/templates/spec/cypress/fixtures/example.json +5 -0
  11. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/actions.spec.js +272 -0
  12. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/aliasing.spec.js +42 -0
  13. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/assertions.spec.js +63 -0
  14. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/connectors.spec.js +55 -0
  15. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/cookies.spec.js +78 -0
  16. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/cypress_api.spec.js +211 -0
  17. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/files.spec.js +86 -0
  18. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/local_storage.spec.js +52 -0
  19. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/location.spec.js +32 -0
  20. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/misc.spec.js +68 -0
  21. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/navigation.spec.js +54 -0
  22. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/network_requests.spec.js +108 -0
  23. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/querying.spec.js +65 -0
  24. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/spies_stubs_clocks.spec.js +62 -0
  25. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/traversal.spec.js +121 -0
  26. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/utilities.spec.js +89 -0
  27. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/viewport.spec.js +59 -0
  28. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/waiting.spec.js +34 -0
  29. data/lib/generators/cypress_dev/templates/spec/cypress/integration/examples/window.spec.js +22 -0
  30. data/lib/generators/cypress_dev/templates/spec/cypress/integration/rails_examples/other_spec.js +25 -0
  31. data/lib/generators/cypress_dev/templates/spec/cypress/integration/rails_examples/using_factory_bot.js +31 -0
  32. data/lib/generators/cypress_dev/templates/spec/cypress/integration/rails_examples/using_fixtures.js +33 -0
  33. data/lib/generators/cypress_dev/templates/spec/cypress/integration/rails_examples/using_scenarios_spec.js +26 -0
  34. data/lib/generators/cypress_dev/templates/spec/cypress/support/on-rails.js +7 -3
  35. data/spec/integrations/cypress.json +5 -0
  36. data/spec/integrations/rails_3_2/app/models/post.rb +4 -0
  37. data/spec/integrations/rails_3_2/app/views/welcome/index.html.erb +24 -5
  38. data/spec/integrations/rails_3_2/test.sh +9 -3
  39. data/spec/integrations/rails_4_2/.gitignore +5 -5
  40. data/spec/integrations/rails_4_2/app/models/post.rb +4 -0
  41. data/spec/integrations/rails_4_2/app/views/welcome/index.html.erb +24 -5
  42. data/spec/integrations/rails_4_2/test.sh +11 -4
  43. data/spec/integrations/rails_5_2/.gitignore +7 -5
  44. data/spec/integrations/rails_5_2/Gemfile +2 -0
  45. data/spec/integrations/rails_5_2/app/assets/javascripts/posts.js +2 -0
  46. data/spec/integrations/rails_5_2/app/assets/stylesheets/posts.css +4 -0
  47. data/spec/integrations/rails_5_2/app/assets/stylesheets/scaffold.css +80 -0
  48. data/spec/integrations/rails_5_2/app/controllers/posts_controller.rb +58 -0
  49. data/spec/integrations/rails_5_2/app/helpers/posts_helper.rb +2 -0
  50. data/spec/integrations/rails_5_2/app/models/application_record.rb +3 -0
  51. data/spec/integrations/rails_5_2/app/models/post.rb +1 -12
  52. data/spec/integrations/rails_5_2/app/views/posts/_form.html.erb +32 -0
  53. data/spec/integrations/rails_5_2/app/views/posts/edit.html.erb +6 -0
  54. data/spec/integrations/rails_5_2/app/views/posts/index.html.erb +31 -0
  55. data/spec/integrations/rails_5_2/app/views/posts/new.html.erb +5 -0
  56. data/spec/integrations/rails_5_2/app/views/posts/show.html.erb +19 -0
  57. data/spec/integrations/rails_5_2/config/application.rb +2 -2
  58. data/spec/integrations/rails_5_2/config/database.yml +15 -0
  59. data/spec/integrations/rails_5_2/config/routes.rb +2 -1
  60. data/spec/integrations/rails_5_2/db/migrate/20180621085832_create_posts.rb +11 -0
  61. data/spec/integrations/rails_5_2/test.sh +14 -5
  62. data/spec/integrations/rails_5_2/test/controllers/posts_controller_test.rb +48 -0
  63. data/spec/integrations/rails_5_2/test/cypress_fixtures/posts.yml +11 -0
  64. data/spec/integrations/rails_5_2/test/fixtures/posts.yml +11 -0
  65. data/spec/integrations/rails_5_2/test/models/post_test.rb +7 -0
  66. metadata +45 -4
  67. data/lib/generators/cypress_dev/templates/spec/cypress/integration/on_rails_spec.js +0 -33
  68. data/spec/integrations/rails_5_2/app/controllers/welcome_controller.rb +0 -4
@@ -0,0 +1,62 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Spies, Stubs, and Clock', () => {
4
+ it('cy.spy() - wrap a method in a spy', () => {
5
+ // https://on.cypress.io/spy
6
+ cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
7
+
8
+ let obj = {
9
+ foo () {},
10
+ }
11
+
12
+ let spy = cy.spy(obj, 'foo').as('anyArgs')
13
+
14
+ obj.foo()
15
+
16
+ expect(spy).to.be.called
17
+ })
18
+
19
+ it('cy.stub() - create a stub and/or replace a function with stub', () => {
20
+ // https://on.cypress.io/stub
21
+ cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
22
+
23
+ let obj = {
24
+ foo () {},
25
+ }
26
+
27
+ let stub = cy.stub(obj, 'foo').as('foo')
28
+
29
+ obj.foo('foo', 'bar')
30
+
31
+ expect(stub).to.be.called
32
+ })
33
+
34
+ it('cy.clock() - control time in the browser', () => {
35
+ // https://on.cypress.io/clock
36
+
37
+ // create the date in UTC so its always the same
38
+ // no matter what local timezone the browser is running in
39
+ let now = new Date(Date.UTC(2017, 2, 14)).getTime()
40
+
41
+ cy.clock(now)
42
+ cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
43
+ cy.get('#clock-div').click()
44
+ .should('have.text', '1489449600')
45
+ })
46
+
47
+ it('cy.tick() - move time in the browser', () => {
48
+ // https://on.cypress.io/tick
49
+
50
+ // create the date in UTC so its always the same
51
+ // no matter what local timezone the browser is running in
52
+ let now = new Date(Date.UTC(2017, 2, 14)).getTime()
53
+
54
+ cy.clock(now)
55
+ cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
56
+ cy.get('#tick-div').click()
57
+ .should('have.text', '1489449600')
58
+ cy.tick(10000) // 10 seconds passed
59
+ cy.get('#tick-div').click()
60
+ .should('have.text', '1489449610')
61
+ })
62
+ })
@@ -0,0 +1,121 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Traversal', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io/commands/traversal')
6
+ })
7
+
8
+ it('.children() - get child DOM elements', () => {
9
+ // https://on.cypress.io/children
10
+ cy.get('.traversal-breadcrumb')
11
+ .children('.active')
12
+ .should('contain', 'Data')
13
+ })
14
+
15
+ it('.closest() - get closest ancestor DOM element', () => {
16
+ // https://on.cypress.io/closest
17
+ cy.get('.traversal-badge')
18
+ .closest('ul')
19
+ .should('have.class', 'list-group')
20
+ })
21
+
22
+ it('.eq() - get a DOM element at a specific index', () => {
23
+ // https://on.cypress.io/eq
24
+ cy.get('.traversal-list>li')
25
+ .eq(1).should('contain', 'siamese')
26
+ })
27
+
28
+ it('.filter() - get DOM elements that match the selector', () => {
29
+ // https://on.cypress.io/filter
30
+ cy.get('.traversal-nav>li')
31
+ .filter('.active').should('contain', 'About')
32
+ })
33
+
34
+ it('.find() - get descendant DOM elements of the selector', () => {
35
+ // https://on.cypress.io/find
36
+ cy.get('.traversal-pagination')
37
+ .find('li').find('a')
38
+ .should('have.length', 7)
39
+ })
40
+
41
+ it('.first() - get first DOM element', () => {
42
+ // https://on.cypress.io/first
43
+ cy.get('.traversal-table td')
44
+ .first().should('contain', '1')
45
+ })
46
+
47
+ it('.last() - get last DOM element', () => {
48
+ // https://on.cypress.io/last
49
+ cy.get('.traversal-buttons .btn')
50
+ .last().should('contain', 'Submit')
51
+ })
52
+
53
+ it('.next() - get next sibling DOM element', () => {
54
+ // https://on.cypress.io/next
55
+ cy.get('.traversal-ul')
56
+ .contains('apples').next().should('contain', 'oranges')
57
+ })
58
+
59
+ it('.nextAll() - get all next sibling DOM elements', () => {
60
+ // https://on.cypress.io/nextall
61
+ cy.get('.traversal-next-all')
62
+ .contains('oranges')
63
+ .nextAll().should('have.length', 3)
64
+ })
65
+
66
+ it('.nextUntil() - get next sibling DOM elements until next el', () => {
67
+ // https://on.cypress.io/nextuntil
68
+ cy.get('#veggies')
69
+ .nextUntil('#nuts').should('have.length', 3)
70
+ })
71
+
72
+ it('.not() - remove DOM elements from set of DOM elements', () => {
73
+ // https://on.cypress.io/not
74
+ cy.get('.traversal-disabled .btn')
75
+ .not('[disabled]').should('not.contain', 'Disabled')
76
+ })
77
+
78
+ it('.parent() - get parent DOM element from DOM elements', () => {
79
+ // https://on.cypress.io/parent
80
+ cy.get('.traversal-mark')
81
+ .parent().should('contain', 'Morbi leo risus')
82
+ })
83
+
84
+ it('.parents() - get parent DOM elements from DOM elements', () => {
85
+ // https://on.cypress.io/parents
86
+ cy.get('.traversal-cite')
87
+ .parents().should('match', 'blockquote')
88
+ })
89
+
90
+ it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => {
91
+ // https://on.cypress.io/parentsuntil
92
+ cy.get('.clothes-nav')
93
+ .find('.active')
94
+ .parentsUntil('.clothes-nav')
95
+ .should('have.length', 2)
96
+ })
97
+
98
+ it('.prev() - get previous sibling DOM element', () => {
99
+ // https://on.cypress.io/prev
100
+ cy.get('.birds').find('.active')
101
+ .prev().should('contain', 'Lorikeets')
102
+ })
103
+
104
+ it('.prevAll() - get all previous sibling DOM elements', () => {
105
+ // https://on.cypress.io/prevAll
106
+ cy.get('.fruits-list').find('.third')
107
+ .prevAll().should('have.length', 2)
108
+ })
109
+
110
+ it('.prevUntil() - get all previous sibling DOM elements until el', () => {
111
+ // https://on.cypress.io/prevUntil
112
+ cy.get('.foods-list').find('#nuts')
113
+ .prevUntil('#veggies').should('have.length', 3)
114
+ })
115
+
116
+ it('.siblings() - get all sibling DOM elements', () => {
117
+ // https://on.cypress.io/siblings
118
+ cy.get('.traversal-pills .active')
119
+ .siblings().should('have.length', 2)
120
+ })
121
+ })
@@ -0,0 +1,89 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Utilities', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io/utilities')
6
+ })
7
+
8
+ it('Cypress._ - call a lodash method', () => {
9
+ // https://on.cypress.io/_
10
+ cy.request('https://jsonplaceholder.typicode.com/users')
11
+ .then((response) => {
12
+ let ids = Cypress._.chain(response.body).map('id').take(3).value()
13
+
14
+ expect(ids).to.deep.eq([1, 2, 3])
15
+ })
16
+ })
17
+
18
+ it('Cypress.$ - call a jQuery method', () => {
19
+ // https://on.cypress.io/$
20
+ let $li = Cypress.$('.utility-jquery li:first')
21
+
22
+ cy.wrap($li)
23
+ .should('not.have.class', 'active')
24
+ .click()
25
+ .should('have.class', 'active')
26
+ })
27
+
28
+ it('Cypress.Blob - blob utilities and base64 string conversion', () => {
29
+ // https://on.cypress.io/blob
30
+ cy.get('.utility-blob').then(($div) =>
31
+ // https://github.com/nolanlawson/blob-util#imgSrcToDataURL
32
+ // get the dataUrl string for the javascript-logo
33
+ Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous')
34
+ .then((dataUrl) => {
35
+ // create an <img> element and set its src to the dataUrl
36
+ let img = Cypress.$('<img />', { src: dataUrl })
37
+ // need to explicitly return cy here since we are initially returning
38
+ // the Cypress.Blob.imgSrcToDataURL promise to our test
39
+ // append the image
40
+ $div.append(img)
41
+
42
+ cy.get('.utility-blob img').click()
43
+ .should('have.attr', 'src', dataUrl)
44
+ }))
45
+ })
46
+
47
+ it('Cypress.minimatch - test out glob patterns against strings', () => {
48
+ // https://on.cypress.io/minimatch
49
+ Cypress.minimatch('/users/1/comments', '/users/*/comments', {
50
+ matchBase: true,
51
+ })
52
+ })
53
+
54
+
55
+ it('Cypress.moment() - format or parse dates using a moment method', () => {
56
+ // https://on.cypress.io/moment
57
+ let time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A')
58
+
59
+ cy.get('.utility-moment').contains('3:38 PM')
60
+ .should('have.class', 'badge')
61
+ })
62
+
63
+
64
+ it('Cypress.Promise - instantiate a bluebird promise', () => {
65
+ // https://on.cypress.io/promise
66
+ let waited = false
67
+
68
+ function waitOneSecond () {
69
+ // return a promise that resolves after 1 second
70
+ return new Cypress.Promise((resolve, reject) => {
71
+ setTimeout(() => {
72
+ // set waited to true
73
+ waited = true
74
+
75
+ // resolve with 'foo' string
76
+ resolve('foo')
77
+ }, 1000)
78
+ })
79
+ }
80
+
81
+ cy.then(() =>
82
+ // return a promise to cy.then() that
83
+ // is awaited until it resolves
84
+ waitOneSecond().then((str) => {
85
+ expect(str).to.eq('foo')
86
+ expect(waited).to.be.true
87
+ }))
88
+ })
89
+ })
@@ -0,0 +1,59 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Viewport', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io/commands/viewport')
6
+ })
7
+
8
+ it('cy.viewport() - set the viewport size and dimension', () => {
9
+ // https://on.cypress.io/viewport
10
+
11
+ cy.get('#navbar').should('be.visible')
12
+ cy.viewport(320, 480)
13
+
14
+ // the navbar should have collapse since our screen is smaller
15
+ cy.get('#navbar').should('not.be.visible')
16
+ cy.get('.navbar-toggle').should('be.visible').click()
17
+ cy.get('.nav').find('a').should('be.visible')
18
+
19
+ // lets see what our app looks like on a super large screen
20
+ cy.viewport(2999, 2999)
21
+
22
+ // cy.viewport() accepts a set of preset sizes
23
+ // to easily set the screen to a device's width and height
24
+
25
+ // We added a cy.wait() between each viewport change so you can see
26
+ // the change otherwise it is a little too fast to see :)
27
+
28
+ cy.viewport('macbook-15')
29
+ cy.wait(200)
30
+ cy.viewport('macbook-13')
31
+ cy.wait(200)
32
+ cy.viewport('macbook-11')
33
+ cy.wait(200)
34
+ cy.viewport('ipad-2')
35
+ cy.wait(200)
36
+ cy.viewport('ipad-mini')
37
+ cy.wait(200)
38
+ cy.viewport('iphone-6+')
39
+ cy.wait(200)
40
+ cy.viewport('iphone-6')
41
+ cy.wait(200)
42
+ cy.viewport('iphone-5')
43
+ cy.wait(200)
44
+ cy.viewport('iphone-4')
45
+ cy.wait(200)
46
+ cy.viewport('iphone-3')
47
+ cy.wait(200)
48
+
49
+ // cy.viewport() accepts an orientation for all presets
50
+ // the default orientation is 'portrait'
51
+ cy.viewport('ipad-2', 'portrait')
52
+ cy.wait(200)
53
+ cy.viewport('iphone-4', 'landscape')
54
+ cy.wait(200)
55
+
56
+ // The viewport will be reset back to the default dimensions
57
+ // in between tests (the default can be set in cypress.json)
58
+ })
59
+ })
@@ -0,0 +1,34 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Waiting', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io/commands/waiting')
6
+ })
7
+ // BE CAREFUL of adding unnecessary wait times.
8
+ // https://on.cypress.io/best-practices#Unnecessary-Waiting
9
+
10
+ // https://on.cypress.io/wait
11
+ it('cy.wait() - wait for a specific amount of time', () => {
12
+ cy.get('.wait-input1').type('Wait 1000ms after typing')
13
+ cy.wait(1000)
14
+ cy.get('.wait-input2').type('Wait 1000ms after typing')
15
+ cy.wait(1000)
16
+ cy.get('.wait-input3').type('Wait 1000ms after typing')
17
+ cy.wait(1000)
18
+ })
19
+
20
+ it('cy.wait() - wait for a specific route', () => {
21
+ cy.server()
22
+
23
+ // Listen to GET to comments/1
24
+ cy.route('GET', 'comments/*').as('getComment')
25
+
26
+ // we have code that gets a comment when
27
+ // the button is clicked in scripts.js
28
+ cy.get('.network-btn').click()
29
+
30
+ // wait for GET comments/1
31
+ cy.wait('@getComment').its('status').should('eq', 200)
32
+ })
33
+
34
+ })
@@ -0,0 +1,22 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Window', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io/commands/window')
6
+ })
7
+
8
+ it('cy.window() - get the global window object', () => {
9
+ // https://on.cypress.io/window
10
+ cy.window().should('have.property', 'top')
11
+ })
12
+
13
+ it('cy.document() - get the document object', () => {
14
+ // https://on.cypress.io/document
15
+ cy.document().should('have.property', 'charset').and('eq', 'UTF-8')
16
+ })
17
+
18
+ it('cy.title() - get the title', () => {
19
+ // https://on.cypress.io/title
20
+ cy.title().should('include', 'Kitchen Sink')
21
+ })
22
+ })
@@ -0,0 +1,25 @@
1
+ describe('Rails Other examples', function() {
2
+ it('cypress eval', function() {
3
+ cy.app('clean') // have a look at cypress/app_commands/clean.rb
4
+ cy.appEval("Post.create(title: 'Hello Eval')")
5
+
6
+ cy.visit('/')
7
+ cy.get('table').find('tbody').should(($tbody) => {
8
+ expect($tbody).not.to.contain('Multi Command')
9
+ expect($tbody).to.contain('Hello Eval')
10
+ })
11
+ })
12
+
13
+ it('runs multiple commands', function() {
14
+ cy.appCommands([{ name: 'clean' },
15
+ { name: 'scenarios/basic' },
16
+ { name: 'eval', options: "Post.create(title: 'Multi Command')" }])
17
+ cy.visit('/')
18
+
19
+ cy.get('table').find('tbody').should(($tbody) => {
20
+ expect($tbody).not.to.contain('Hello Eval')
21
+ expect($tbody).to.contain('Multi Command')
22
+ expect($tbody).to.contain('I am a Postman')
23
+ })
24
+ })
25
+ })
@@ -0,0 +1,31 @@
1
+ describe('Rails using factory bot examples', function() {
2
+ beforeEach(() => {
3
+ cy.app('clean') // have a look at cypress/app_commands/clean.rb
4
+ })
5
+
6
+ it('using single factory bot', function() {
7
+ cy.appFactories([
8
+ ['create', 'post', {title: 'Good bye Mars'} ]
9
+ ])
10
+ cy.visit('/')
11
+ cy.get('table').find('tbody').should(($tbody) => {
12
+ // clean should of removed these from other tests
13
+ expect($tbody).not.to.contain('Hello World')
14
+
15
+ expect($tbody).to.contain('Good bye Mars')
16
+ })
17
+ })
18
+
19
+ it('using multiple factory bot', function() {
20
+ cy.appFactories([
21
+ ['create_list', 'post', 10],
22
+ ['create', 'post', {title: 'Hello World'} ]
23
+ ])
24
+ cy.visit('/')
25
+ cy.get('table').find('tbody').should(($tbody) => {
26
+ // clean should of removed these from other tests
27
+ expect($tbody).to.contain('Hello World')
28
+ expect($tbody).not.to.contain('Good bye Mars')
29
+ })
30
+ })
31
+ })