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,86 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Files', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io/commands/files')
6
+ })
7
+ it('cy.fixture() - load a fixture', () => {
8
+ // https://on.cypress.io/fixture
9
+
10
+ // Instead of writing a response inline you can
11
+ // use a fixture file's content.
12
+
13
+ cy.server()
14
+ cy.fixture('example.json').as('comment')
15
+ cy.route('GET', 'comments/*', '@comment').as('getComment')
16
+
17
+ // we have code that gets a comment when
18
+ // the button is clicked in scripts.js
19
+ cy.get('.fixture-btn').click()
20
+
21
+ cy.wait('@getComment').its('responseBody')
22
+ .should('have.property', 'name')
23
+ .and('include', 'Using fixtures to represent data')
24
+
25
+ // you can also just write the fixture in the route
26
+ cy.route('GET', 'comments/*', 'fixture:example.json').as('getComment')
27
+
28
+ // we have code that gets a comment when
29
+ // the button is clicked in scripts.js
30
+ cy.get('.fixture-btn').click()
31
+
32
+ cy.wait('@getComment').its('responseBody')
33
+ .should('have.property', 'name')
34
+ .and('include', 'Using fixtures to represent data')
35
+
36
+ // or write fx to represent fixture
37
+ // by default it assumes it's .json
38
+ cy.route('GET', 'comments/*', 'fx:example').as('getComment')
39
+
40
+ // we have code that gets a comment when
41
+ // the button is clicked in scripts.js
42
+ cy.get('.fixture-btn').click()
43
+
44
+ cy.wait('@getComment').its('responseBody')
45
+ .should('have.property', 'name')
46
+ .and('include', 'Using fixtures to represent data')
47
+ })
48
+
49
+ it('cy.readFile() - read a files contents', () => {
50
+ // https://on.cypress.io/readfile
51
+
52
+ // You can read a file and yield its contents
53
+ // The filePath is relative to your project's root.
54
+ cy.readFile('cypress.json').then((json) => {
55
+ expect(json).to.be.an('object')
56
+ })
57
+ })
58
+
59
+ it('cy.writeFile() - write to a file', () => {
60
+ // https://on.cypress.io/writefile
61
+
62
+ // You can write to a file
63
+
64
+ // Use a response from a request to automatically
65
+ // generate a fixture file for use later
66
+ cy.request('https://jsonplaceholder.typicode.com/users')
67
+ .then((response) => {
68
+ cy.writeFile('cypress/fixtures/users.json', response.body)
69
+ })
70
+ cy.fixture('users').should((users) => {
71
+ expect(users[0].name).to.exist
72
+ })
73
+
74
+ // JavaScript arrays and objects are stringified
75
+ // and formatted into text.
76
+ cy.writeFile('cypress/fixtures/profile.json', {
77
+ id: 8739,
78
+ name: 'Jane',
79
+ email: 'jane@example.com',
80
+ })
81
+
82
+ cy.fixture('profile').should((profile) => {
83
+ expect(profile.name).to.eq('Jane')
84
+ })
85
+ })
86
+ })
@@ -0,0 +1,52 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Local Storage', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io/commands/local-storage')
6
+ })
7
+ // Although local storage is automatically cleared
8
+ // in between tests to maintain a clean state
9
+ // sometimes we need to clear the local storage manually
10
+
11
+ it('cy.clearLocalStorage() - clear all data in local storage', () => {
12
+ // https://on.cypress.io/clearlocalstorage
13
+ cy.get('.ls-btn').click().should(() => {
14
+ expect(localStorage.getItem('prop1')).to.eq('red')
15
+ expect(localStorage.getItem('prop2')).to.eq('blue')
16
+ expect(localStorage.getItem('prop3')).to.eq('magenta')
17
+ })
18
+
19
+ // clearLocalStorage() yields the localStorage object
20
+ cy.clearLocalStorage().should((ls) => {
21
+ expect(ls.getItem('prop1')).to.be.null
22
+ expect(ls.getItem('prop2')).to.be.null
23
+ expect(ls.getItem('prop3')).to.be.null
24
+ })
25
+
26
+ // Clear key matching string in Local Storage
27
+ cy.get('.ls-btn').click().should(() => {
28
+ expect(localStorage.getItem('prop1')).to.eq('red')
29
+ expect(localStorage.getItem('prop2')).to.eq('blue')
30
+ expect(localStorage.getItem('prop3')).to.eq('magenta')
31
+ })
32
+
33
+ cy.clearLocalStorage('prop1').should((ls) => {
34
+ expect(ls.getItem('prop1')).to.be.null
35
+ expect(ls.getItem('prop2')).to.eq('blue')
36
+ expect(ls.getItem('prop3')).to.eq('magenta')
37
+ })
38
+
39
+ // Clear keys matching regex in Local Storage
40
+ cy.get('.ls-btn').click().should(() => {
41
+ expect(localStorage.getItem('prop1')).to.eq('red')
42
+ expect(localStorage.getItem('prop2')).to.eq('blue')
43
+ expect(localStorage.getItem('prop3')).to.eq('magenta')
44
+ })
45
+
46
+ cy.clearLocalStorage(/prop1|2/).should((ls) => {
47
+ expect(ls.getItem('prop1')).to.be.null
48
+ expect(ls.getItem('prop2')).to.be.null
49
+ expect(ls.getItem('prop3')).to.eq('magenta')
50
+ })
51
+ })
52
+ })
@@ -0,0 +1,32 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Location', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io/commands/location')
6
+ })
7
+
8
+ it('cy.hash() - get the current URL hash', () => {
9
+ // https://on.cypress.io/hash
10
+ cy.hash().should('be.empty')
11
+ })
12
+
13
+ it('cy.location() - get window.location', () => {
14
+ // https://on.cypress.io/location
15
+ cy.location().should((location) => {
16
+ expect(location.hash).to.be.empty
17
+ expect(location.href).to.eq('https://example.cypress.io/commands/location')
18
+ expect(location.host).to.eq('example.cypress.io')
19
+ expect(location.hostname).to.eq('example.cypress.io')
20
+ expect(location.origin).to.eq('https://example.cypress.io')
21
+ expect(location.pathname).to.eq('/commands/location')
22
+ expect(location.port).to.eq('')
23
+ expect(location.protocol).to.eq('https:')
24
+ expect(location.search).to.be.empty
25
+ })
26
+ })
27
+
28
+ it('cy.url() - get the current URL', () => {
29
+ // https://on.cypress.io/url
30
+ cy.url().should('eq', 'https://example.cypress.io/commands/location')
31
+ })
32
+ })
@@ -0,0 +1,68 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Misc', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io/commands/misc')
6
+ })
7
+
8
+ it('.end() - end the command chain', () => {
9
+ // https://on.cypress.io/end
10
+
11
+ // cy.end is useful when you want to end a chain of commands
12
+ // and force Cypress to re-query from the root element
13
+ cy.get('.misc-table').within(() => {
14
+ // ends the current chain and yields null
15
+ cy.contains('Cheryl').click().end()
16
+
17
+ // queries the entire table again
18
+ cy.contains('Charles').click()
19
+ })
20
+ })
21
+
22
+ it('cy.exec() - execute a system command', () => {
23
+ // https://on.cypress.io/exec
24
+
25
+ // execute a system command.
26
+ // so you can take actions necessary for
27
+ // your test outside the scope of Cypress.
28
+ cy.exec('echo Jane Lane')
29
+ .its('stdout').should('contain', 'Jane Lane')
30
+
31
+ // we can use Cypress.platform string to
32
+ // select appropriate command
33
+ // https://on.cypress/io/platform
34
+ cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`)
35
+
36
+ if (Cypress.platform === 'win32') {
37
+ cy.exec('print cypress.json')
38
+ .its('stderr').should('be.empty')
39
+ } else {
40
+ cy.exec('cat cypress.json')
41
+ .its('stderr').should('be.empty')
42
+
43
+ cy.exec('pwd')
44
+ .its('code').should('eq', 0)
45
+ }
46
+ })
47
+
48
+ it('cy.focused() - get the DOM element that has focus', () => {
49
+ // https://on.cypress.io/focused
50
+ cy.get('.misc-form').find('#name').click()
51
+ cy.focused().should('have.id', 'name')
52
+
53
+ cy.get('.misc-form').find('#description').click()
54
+ cy.focused().should('have.id', 'description')
55
+ })
56
+
57
+ it('cy.screenshot() - take a screenshot', () => {
58
+ // https://on.cypress.io/screenshot
59
+ cy.screenshot('my-image')
60
+ })
61
+
62
+ it('cy.wrap() - wrap an object', () => {
63
+ // https://on.cypress.io/wrap
64
+ cy.wrap({ foo: 'bar' })
65
+ .should('have.property', 'foo')
66
+ .and('include', 'bar')
67
+ })
68
+ })
@@ -0,0 +1,54 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Navigation', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io')
6
+ cy.get('.navbar-nav').contains('Commands').click()
7
+ cy.get('.dropdown-menu').contains('Navigation').click()
8
+ })
9
+
10
+ it('cy.go() - go back or forward in the browser\'s history', () => {
11
+ // https://on.cypress.io/go
12
+
13
+ cy.location('pathname').should('include', 'navigation')
14
+
15
+ cy.go('back')
16
+ cy.location('pathname').should('not.include', 'navigation')
17
+
18
+ cy.go('forward')
19
+ cy.location('pathname').should('include', 'navigation')
20
+
21
+ // clicking back
22
+ cy.go(-1)
23
+ cy.location('pathname').should('not.include', 'navigation')
24
+
25
+ // clicking forward
26
+ cy.go(1)
27
+ cy.location('pathname').should('include', 'navigation')
28
+ })
29
+
30
+ it('cy.reload() - reload the page', () => {
31
+ // https://on.cypress.io/reload
32
+ cy.reload()
33
+
34
+ // reload the page without using the cache
35
+ cy.reload(true)
36
+ })
37
+
38
+ it('cy.visit() - visit a remote url', () => {
39
+ // https://on.cypress.io/visit
40
+
41
+ // Visit any sub-domain of your current domain
42
+
43
+ // Pass options to the visit
44
+ cy.visit('https://example.cypress.io/commands/navigation', {
45
+ timeout: 50000, // increase total time for the visit to resolve
46
+ onBeforeLoad (contentWindow) {
47
+ // contentWindow is the remote page's window object
48
+ },
49
+ onLoad (contentWindow) {
50
+ // contentWindow is the remote page's window object
51
+ },
52
+ })
53
+ })
54
+ })
@@ -0,0 +1,108 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Network Requests', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io/commands/network-requests')
6
+ })
7
+
8
+ // Manage AJAX / XHR requests in your app
9
+
10
+ it('cy.server() - control behavior of network requests and responses', () => {
11
+ // https://on.cypress.io/server
12
+
13
+ cy.server().should((server) => {
14
+ // the default options on server
15
+ // you can override any of these options
16
+ expect(server.delay).to.eq(0)
17
+ expect(server.method).to.eq('GET')
18
+ expect(server.status).to.eq(200)
19
+ expect(server.headers).to.be.null
20
+ expect(server.response).to.be.null
21
+ expect(server.onRequest).to.be.undefined
22
+ expect(server.onResponse).to.be.undefined
23
+ expect(server.onAbort).to.be.undefined
24
+
25
+ // These options control the server behavior
26
+ // affecting all requests
27
+
28
+ // pass false to disable existing route stubs
29
+ expect(server.enable).to.be.true
30
+ // forces requests that don't match your routes to 404
31
+ expect(server.force404).to.be.false
32
+ // whitelists requests from ever being logged or stubbed
33
+ expect(server.whitelist).to.be.a('function')
34
+ })
35
+
36
+ cy.server({
37
+ method: 'POST',
38
+ delay: 1000,
39
+ status: 422,
40
+ response: {},
41
+ })
42
+
43
+ // any route commands will now inherit the above options
44
+ // from the server. anything we pass specifically
45
+ // to route will override the defaults though.
46
+ })
47
+
48
+ it('cy.request() - make an XHR request', () => {
49
+ // https://on.cypress.io/request
50
+ cy.request('https://jsonplaceholder.typicode.com/comments')
51
+ .should((response) => {
52
+ expect(response.status).to.eq(200)
53
+ expect(response.body).to.have.length(500)
54
+ expect(response).to.have.property('headers')
55
+ expect(response).to.have.property('duration')
56
+ })
57
+ })
58
+
59
+ it('cy.route() - route responses to matching requests', () => {
60
+ // https://on.cypress.io/route
61
+
62
+ let message = 'whoa, this comment does not exist'
63
+ cy.server()
64
+
65
+ // Listen to GET to comments/1
66
+ cy.route('GET', 'comments/*').as('getComment')
67
+
68
+ // we have code that gets a comment when
69
+ // the button is clicked in scripts.js
70
+ cy.get('.network-btn').click()
71
+
72
+ // https://on.cypress.io/wait
73
+ cy.wait('@getComment').its('status').should('eq', 200)
74
+
75
+ // Listen to POST to comments
76
+ cy.route('POST', '/comments').as('postComment')
77
+
78
+ // we have code that posts a comment when
79
+ // the button is clicked in scripts.js
80
+ cy.get('.network-post').click()
81
+ cy.wait('@postComment')
82
+
83
+ // get the route
84
+ cy.get('@postComment').should((xhr) => {
85
+ expect(xhr.requestBody).to.include('email')
86
+ expect(xhr.requestHeaders).to.have.property('Content-Type')
87
+ expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()')
88
+ })
89
+
90
+ // Stub a response to PUT comments/ ****
91
+ cy.route({
92
+ method: 'PUT',
93
+ url: 'comments/*',
94
+ status: 404,
95
+ response: { error: message },
96
+ delay: 500,
97
+ }).as('putComment')
98
+
99
+ // we have code that puts a comment when
100
+ // the button is clicked in scripts.js
101
+ cy.get('.network-put').click()
102
+
103
+ cy.wait('@putComment')
104
+
105
+ // our 404 statusCode logic in scripts.js executed
106
+ cy.get('.network-put-comment').should('contain', message)
107
+ })
108
+ })
@@ -0,0 +1,65 @@
1
+ /// <reference types="Cypress" />
2
+
3
+ context('Querying', () => {
4
+ beforeEach(() => {
5
+ cy.visit('https://example.cypress.io/commands/querying')
6
+ })
7
+
8
+ // The most commonly used query is 'cy.get()', you can
9
+ // think of this like the '$' in jQuery
10
+
11
+ it('cy.get() - query DOM elements', () => {
12
+ // https://on.cypress.io/get
13
+
14
+ cy.get('#query-btn').should('contain', 'Button')
15
+
16
+ cy.get('.query-btn').should('contain', 'Button')
17
+
18
+ cy.get('#querying .well>button:first').should('contain', 'Button')
19
+ // ↲
20
+ // Use CSS selectors just like jQuery
21
+ })
22
+
23
+ it('cy.contains() - query DOM elements with matching content', () => {
24
+ // https://on.cypress.io/contains
25
+ cy.get('.query-list')
26
+ .contains('bananas').should('have.class', 'third')
27
+
28
+ // we can pass a regexp to `.contains()`
29
+ cy.get('.query-list')
30
+ .contains(/^b\w+/).should('have.class', 'third')
31
+
32
+ cy.get('.query-list')
33
+ .contains('apples').should('have.class', 'first')
34
+
35
+ // passing a selector to contains will
36
+ // yield the selector containing the text
37
+ cy.get('#querying')
38
+ .contains('ul', 'oranges')
39
+ .should('have.class', 'query-list')
40
+
41
+ cy.get('.query-button')
42
+ .contains('Save Form')
43
+ .should('have.class', 'btn')
44
+ })
45
+
46
+ it('.within() - query DOM elements within a specific element', () => {
47
+ // https://on.cypress.io/within
48
+ cy.get('.query-form').within(() => {
49
+ cy.get('input:first').should('have.attr', 'placeholder', 'Email')
50
+ cy.get('input:last').should('have.attr', 'placeholder', 'Password')
51
+ })
52
+ })
53
+
54
+ it('cy.root() - query the root DOM element', () => {
55
+ // https://on.cypress.io/root
56
+
57
+ // By default, root is the document
58
+ cy.root().should('match', 'html')
59
+
60
+ cy.get('.query-ul').within(() => {
61
+ // In this within, the root is now the ul DOM element
62
+ cy.root().should('have.class', 'query-ul')
63
+ })
64
+ })
65
+ })