last
Get the last DOM element within a set of DOM elements.
The querying behavior of this command matches exactly how
.last() works in jQuery.
Syntax​
.last()
.last(options)
Usage​
Correct Usage
cy.get('nav a').last() // Yield last link in nav
Incorrect Usage
cy.last() // Errors, cannot be chained off 'cy'
cy.getCookies().last() // Errors, 'getCookies' does not yield DOM element
Arguments​
options (Object)
Pass in an options object to change the default behavior of .last().
| Option | Default | Description |
|---|---|---|
log | true | Displays the command in the Command log |
timeout | defaultCommandTimeout | Time to wait for .last() to resolve before timing out |
Yields ​
.last()yields the last DOM element within the set it was given..last()is a query, and it is safe to chain further commands.
Examples​
No Args​
Get the last list item in a list​
<ul>
<li class="one">Knick knack on my thumb</li>
<li class="two">Knick knack on my shoe</li>
<li class="three">Knick knack on my knee</li>
<li class="four">Knick knack on my door</li>
</ul>
// yields <li class="four">Knick knack on my door</li>
cy.get('li').last()
Assert on the newest item after adding one with .last()​
A new item often renders at the end of a list after a request resolves. Chain an
assertion off .last(), and Cypress re-runs the query until the new item is the
last one and the assertion passes.
<input class="new-todo" />
<ul class="todo-list">
<li>Buy milk</li>
</ul>
<!-- pressing Enter in .new-todo sends a request, then adds the text as a new <li> at the end of the list -->
cy.get('.new-todo').type('Write docs{enter}')
cy.get('.todo-list li').last().should('have.text', 'Write docs')
Act on the last row of a table with .last()​
.last() yields a DOM element, so you can keep chaining queries and actions off
it.
<table>
<tbody>
<tr>
<td>Ada</td>
<td><button>Delete</button></td>
</tr>
<tr>
<td>Grace</td>
<td><button>Delete</button></td>
</tr>
</tbody>
</table>
<!-- clicking a Delete button removes its row -->
cy.get('tbody tr').last().find('td').first().should('have.text', 'Grace')
cy.get('tbody tr').last().find('button').click()
cy.get('tbody tr').should('have.length', 1)
Options​
Wait longer for the last element with the timeout option​
The timeout you pass to .last() sets how long Cypress retries the whole
query chain, including the cy.get() before it. Here, the second notification
appears after 6 seconds, which is past the default 4-second
defaultCommandTimeout.
<div class="notification">Saved</div>
<!-- a second .notification with the text "Synced" is added after 6 seconds -->
cy.get('.notification').last({ timeout: 10000 }).should('have.text', 'Synced')
Notes​
How .last() compares to .eq(-1)​
.last() yields the same element as .eq(-1). Use .eq()
to get an element at any other index, including negative indexes counted back
from the end of the set.
Selecting the last element that matches a selector​
.last() takes no selector. cy.get('li').last('.active') yields the last
<li> whether or not it has the class active. The Command Log still shows
.active as the command's message, which can make it look as though the
selector was applied:

TypeScript flags the call as an error. To get the last
element that matches a selector, narrow the set with
.filter() before calling .last().
cy.get('li').filter('.active').last()
How .last() compares to the :last-child selector​
.last() yields a single element, the last one in the whole set. The CSS
:last-child selector matches the last child of each parent, so it can match
several elements when the set spans more than one parent.
<ul class="fruits">
<li>Apple</li>
<li>Banana</li>
</ul>
<ul class="veggies">
<li>Carrot</li>
<li>Daikon</li>
</ul>
cy.get('li').last() // yields <li>Daikon</li>
cy.get('li:last-child') // yields <li>Banana</li> and <li>Daikon</li>
Click a row in the Command Log to pin its snapshot and highlight the elements it
yielded. Pinning last highlights only Daikon:

Pinning get li:last-child highlights Banana and Daikon, the last item in each
list:

Aliasing the result of .last()​
An alias stores the query chain, not the element it found. Each time you use the
alias, Cypress re-runs the chain against the current DOM, so an aliased
.last() always yields the element that is last now. Learn more in
aliasing DOM elements.
Using the to-do list from the newest item example:
cy.get('.todo-list li').last().as('newest')
cy.get('@newest').should('have.text', 'Buy milk')
cy.get('.new-todo').type('Write docs{enter}')
cy.get('@newest').should('have.text', 'Write docs')
Rules​
Requirements ​
.last()requires being chained off a command that yields DOM element(s) or a document.
Assertions ​
.last()will automatically retry until the element(s) exist in the DOM..last()will automatically retry until all chained assertions have passed.
Timeouts ​
.last()can time out waiting for the element(s) to exist in the DOM..last()can time out waiting for assertions you've added to pass.
Command Log​
Find the last button in the form
cy.get('form').find('button').last()
The commands above display in the Command Log as:

Click the last command in the Command Log to print the following to the
console:

History​
| Version | Changes |
|---|---|
| 12.6.0 | Overwrite .last() with Cypress.Commands.overwriteQuery() rather than Cypress.Commands.overwrite(). |
| 12.0.0 | .last() is now a query. |