# Aliasing
Examples of referencing DOM elements or resources for later use in Cypress, for a full reference of commands, go to docs.cypress.io
# .as
# Alias a DOM element
<table class="as-table table table-bordered">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Row 1: Cell 1
<button class="btn btn-primary">Change</button>
</td>
<td>
Row 1: Cell 2
<button class="btn btn-primary">Change</button>
</td>
</tr>
<tr>
<td>
Row 2: Cell 1
<button class="btn btn-primary">Change</button>
</td>
<td>
Row 2: Cell 2
<button class="btn btn-primary">Change</button>
</td>
</tr>
</tbody>
</table>
<script>
$('.as-table .btn').on('click', function (e) {
e.preventDefault()
$(e.currentTarget).addClass('btn-success').text('Changed')
})
</script>
Column 1 | Column 2 |
---|---|
Row 1: Cell 1 | Row 1: Cell 2 |
Row 2: Cell 1 | Row 2: Cell 2 |
// Alias a DOM element for use later
// We don't have to traverse to the element
// later in our code, we reference it with @
cy.get('.as-table')
.find('tbody>tr')
.first()
.find('td')
.first()
.find('button')
.as('firstBtn')
// when we reference the alias, we place an
// @ in front of its name
cy.get('@firstBtn').click()
cy.get('@firstBtn')
.should('have.class', 'btn-success')
.and('contain', 'Changed')
# List example
Another example of aliasing a DOM element
<ul data-cy="query-the-alias">
<li>Apple</li>
<li>Banana</li>
<li>Grape</li>
</ul>
- Apple
- Banana
- Grape
cy.get('[data-cy=query-the-alias]').as('fruits')
// now we can use cy.get to grab the DOM element
cy.get('@fruits')
.should('have.prop', 'tagName', 'UL')
.and('be.visible')
// find child elements
cy.get('@fruits').find('li').should('have.length', 3)
cy.get('@fruits').contains('li', 'Banana')
cy.get('@fruits').contains('li', 'Grape')
Note: if all the assertions related to the DOM elements are grouped together, it is simpler to use cy.within command.
cy.log('**equivalent code using cy.within**')
cy.get('[data-cy=query-the-alias]').within(() => {
cy.root().should('have.prop', 'tagName', 'UL').and('be.visible')
cy.get('li').should('have.length', 3)
cy.contains('li', 'Banana')
cy.contains('li', 'Grape')
})
# Alias a network route
<button class="network-btn btn btn-primary">Get Comment</button>
<div class="network-comment"></div>
<script>
function getComment() {
// we fetch all data from this REST json backend
const root = 'https://jsonplaceholder.cypress.io'
$.ajax({
url: `${root}/comments/1`,
method: 'GET',
}).then(function (data) {
$('.network-comment').text(data.body)
})
}
$('.network-btn').on('click', function (e) {
e.preventDefault()
getComment(e)
})
</script>
// Alias the route to wait for its response
cy.server()
cy.route('GET', 'comments/*').as('getComment')
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.network-btn').click()
// https://on.cypress.io/wait
cy.wait('@getComment').its('status').should('eq', 200)
# Alias values
<button data-cy="magic-number">42</button>
// retrieve the element's text and convert into a number
cy.get('[data-cy=magic-number]')
.invoke('text')
.then(parseInt)
.as('magicNumber')
// saved the value 42 under an alias
// retrieve it some time later
cy.get('@magicNumber').should('equal', 42)
# Test context
The aliased values are set as properties in the test context
object. You can retrieve them later using this.alias
syntax if you use the function () {...}
callback syntax.
Let's confirm the two list items have different text.
<ul data-cy="test-context">
<li>Purple</li>
<li>Orange</li>
</ul>
- Purple
- Orange
cy.get('[data-cy=test-context] li').first().invoke('text').as('first')
cy.get('[data-cy=test-context] li')
.eq(1)
.invoke('text')
.as('second')
.then(function () {
// by the time this callback runs
// both "first" and "second" properties are set
// notice the "function () {...}" syntax
// to get the "this" to point at the test context object
expect(this.first)
.to.equal('Purple') // sanity check
.and.not.equal(this.second)
})
Alternatively, we could have used .then
callbacks to get a "pyramid of Doom"
cy.log('**using callbacks**')
cy.get('[data-cy=test-context] li')
.first()
.invoke('text')
.then((first) => {
cy.get('[data-cy=test-context] li')
.eq(1)
.invoke('text')
.then((second) => {
expect(first)
.to.equal('Purple') // sanity check
.and.not.equal(second)
})
})
Finally, we could have used local variables
let first, second
cy.log('**using variables**')
cy.get('[data-cy=test-context] li')
.first()
.invoke('text')
.then((x) => (first = x))
cy.get('[data-cy=test-context] li')
.eq(1)
.invoke('text')
.then((x) => (second = x))
// by the time this callback runs, both local
// variables are set
cy.then((second) => {
expect(first)
.to.equal('Purple') // sanity check
.and.not.equal(second)
})