-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
logging-in-html-web-form-spec.cy.js
167 lines (142 loc) · 5.58 KB
/
logging-in-html-web-form-spec.cy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/// <reference types="cypress" />
// This recipe is very similar to the 'Logging In - XHR web form'
// except that is uses regular HTML form submission
// instead of using XHR's.
// We are going to test a few things:
// 1. Test unauthorized routes using cy.visit + cy.request
// 2. Test using a regular form submission (old school POSTs)
// 3. Test error states
// 4. Test authenticated session states
// 5. Use cy.request for much faster performance
// 6. Create a custom command
// Be sure to run `npm start` to start the server
// before running the tests below.
describe('Logging In - HTML Web Form', function () {
// we can use these values to log in
const username = 'jane.lane'
const password = 'password123'
context('Unauthorized', function () {
it('is redirected on visit to /dashboard when no session', function () {
// we must have a valid session cookie to be logged
// in else we are redirected to /unauthorized
cy.visit('/dashboard')
cy.get('h3').should(
'contain',
'You are not logged in and cannot access this page'
)
cy.url().should('include', 'unauthorized')
})
it('is redirected using cy.request', function () {
// instead of visiting the page above we can test this by issuing
// a cy.request, checking the status code and redirectedToUrl property.
// See docs for cy.request: https://on.cypress.io/api/request
// the 'redirectedToUrl' property is a special Cypress property under the hood
// that normalizes the url the browser would normally follow during a redirect
cy.request({
url: '/dashboard',
followRedirect: false, // turn off following redirects automatically
}).then((resp) => {
// should have status code 302
expect(resp.status).to.eq(302)
// when we turn off following redirects Cypress will also send us
// a 'redirectedToUrl' property with the fully qualified URL that we
// were redirected to.
expect(resp.redirectedToUrl).to.eq('http://localhost:7077/unauthorized')
})
})
})
context('HTML form submission', function () {
beforeEach(function () {
cy.visit('/login')
})
it('displays errors on login', function () {
// incorrect username on purpose
cy.get('input[name=username]').type('jane.lae')
cy.get('input[name=password]').type('password123{enter}')
// we should have visible errors now
cy.get('p.error')
.should('be.visible')
.and('contain', 'Username and/or password is incorrect')
// and still be on the same URL
cy.url().should('include', '/login')
})
it('redirects to /dashboard on success', function () {
cy.get('input[name=username]').type(username)
cy.get('input[name=password]').type(password)
cy.get('form').submit()
// we should be redirected to /dashboard
cy.url().should('include', '/dashboard')
cy.get('h1').should('contain', 'jane.lane')
// and our cookie should be set to 'cypress-session-cookie'
cy.getCookie('cypress-session-cookie').should('exist')
})
})
context('HTML form submission with cy.request', function () {
it('can bypass the UI and yet still test log in', function () {
// oftentimes once we have a proper e2e test around logging in
// there is NO more reason to actually use our UI to log in users
// doing so wastes is slow because our entire page has to load,
// all associated resources have to load, we have to fill in the
// form, wait for the form submission and redirection process
//
// with cy.request we can bypass this because it automatically gets
// and sets cookies under the hood. This acts exactly as if the requests
// came from the browser
cy.request({
method: 'POST',
url: '/login', // baseUrl will be prepended to this url
form: true, // indicates the body should be form urlencoded and sets Content-Type: application/x-www-form-urlencoded headers
body: {
username,
password,
},
})
// just to prove we have a session
cy.getCookie('cypress-session-cookie').should('exist')
})
})
context('Reusable "login" custom command', function () {
// typically we'd put this in cypress/support/commands.js
// but because this custom command is specific to this example
// we'll keep it here
Cypress.Commands.add('loginByForm', (username, password) => {
Cypress.log({
name: 'loginByForm',
message: `${username} | ${password}`,
})
return cy.request({
method: 'POST',
url: '/login',
form: true,
body: {
username,
password,
},
})
})
beforeEach(function () {
// login before each test
cy.loginByForm(username, password)
})
it('can visit /dashboard', function () {
// after cy.request, the session cookie has been set
// and we can visit a protected page
cy.visit('/dashboard')
cy.get('h1').should('contain', 'jane.lane')
})
it('can visit /users', function () {
// or another protected page
cy.visit('/users')
cy.get('h1').should('contain', 'Users')
})
it('can simply request other authenticated pages', function () {
// instead of visiting each page and waiting for all
// the associated resources to load, we can instead
// just issue a simple HTTP request and make an
// assertion about the response body
cy.request('/admin')
.its('body')
.should('include', '<h1>Admin</h1>')
})
})
})