You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The test first searches for the login button by its text and clicks the button with the command [cy.click](https://docs.cypress.io/api/commands/click.html#Syntax).
167
+
The test first searches for a _button_ element with the desired text and clicks the button with the command [cy.click](https://docs.cypress.io/api/commands/click.html#Syntax).
168
168
169
169
Both of our tests begin the same way, by opening the page <i><http://localhost:5173></i>, so we should extract the shared code into a <i>beforeEach</i> block run before each test:
@@ -195,40 +195,72 @@ We can access the first and the last input field on the page, and write to them
195
195
196
196
```js
197
197
it('user can login', function () {
198
-
cy.contains('login').click()
198
+
cy.contains('button', 'login').click()
199
199
cy.get('input:first').type('mluukkai')
200
200
cy.get('input:last').type('salainen')
201
201
})
202
202
```
203
203
204
204
The test works. The problem is if we later add more input fields, the test will break because it expects the fields it needs to be the first and the last on the page.
205
205
206
-
It would be better to give our inputs unique <i>IDs</i> and use those to find them.
207
-
We change our login form like so:
206
+
Let's take advantage of the existing elements of the login form. The input fields of the login form have been assigned unique <i>labels</i>:
207
+
208
+
```js
209
+
// ...
210
+
<form onSubmit={handleSubmit}>
211
+
<div>
212
+
<label>// highlight-line
213
+
username // highlight-line
214
+
<input
215
+
type="text"
216
+
value={username}
217
+
onChange={handleUsernameChange}
218
+
/>
219
+
</label>// highlight-line
220
+
</div>
221
+
<div>
222
+
<label>// highlight-line
223
+
password // highlight-line
224
+
<input
225
+
type="password"
226
+
value={password}
227
+
onChange={handlePasswordChange}
228
+
/>
229
+
</label>// highlight-line
230
+
</div>
231
+
<button type="submit">login</button>
232
+
</form>
233
+
// ...
234
+
```
235
+
236
+
Input fields can and should be located in tests using <i>labels</i>:
When locating elements, it makes sense to aim to utilize the content visible to the user in the interface, as this best simulates how a user would actually find the desired input field while navigating the application.
251
+
252
+
When the username and password have been entered into the form, the next step is to press the <i>login</i> button. However, this causes a bit of a headache, since there are actually two <i>login</i> buttons on the page. The <i>Togglable</i> component we are using also contains a button with the same name, which is hidden by giving it the visibility attribute style="display: none" when the login form is visible.
253
+
254
+
To ensure that the test clicks the correct button, we assign a unique <i>id</i> attribute to the login form’s <i>login</i> button:
The last row ensures that the login was successful.
260
290
261
-
Note that the CSS's [ID selector](https://developer.mozilla.org/en-US/docs/Web/CSS/ID_selectors) is #, so if we want to search for an element with the ID <i>username</i> the CSS selector is <i>#username</i>.
291
+
Note that the CSS's [ID selector](https://developer.mozilla.org/en-US/docs/Web/CSS/ID_selectors) is #, so if we want to search for an element with the ID <i>login-button</i> the CSS selector is <i>#login-button</i>.
262
292
263
293
Please note that passing the test at this stage requires that there is a user in the test database of the backend test environment, whose username is <i>mluukkai</i> and the password is <i>salainen</i>. Create a user if needed!
0 commit comments