Open In App

Cypress - prevAll() Method

Last Updated : 06 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

The prevAll() method in Cypress is a powerful tool for traversing the DOM to interact with or validate elements that come before a specified element. This method is particularly useful when you need to select all preceding siblings of a given element within the same parent. By traversing backward through the sibling elements, prevAll() allows you to access and perform operations on elements that precede a particular element in the DOM hierarchy.

Key Features:

  • Sibling Traversal: prevAll() targets siblings that appear before the specified element, making it possible to manipulate or verify elements that precede it.
  • Selection Flexibility: The method can be used to filter results by providing a selector, allowing for a more precise selection of preceding siblings.
  • DOM Manipulation: By selecting preceding siblings, you can perform various actions, such as asserting attributes, checking content, or simulating interactions.

Usages of the prevAll() Method in Cypress

The prevAll() method in Cypress is a versatile command for traversing and interacting with preceding siblings in the DOM. Here are some common use cases for prevAll() in Cypress testing:

1. Validating Visibility of Preceding Elements

You need to verify that all elements before a certain item in a list are visible. This can be useful when you want to ensure that the display state of earlier elements is correct before interacting with a specific element.

Example:

JavaScript
cy.get('.target-item').prevAll().should('be.visible');
  • cy.get('.target-item') selects the target element.
  • .prevAll() selects all preceding siblings.
  • should('be.visible') asserts that all preceding elements are visible on the page.

2. Checking Content or State of Previous Elements

You want to ensure that all preceding items in a list have a specific class or text content before performing actions on a target item.

Example:

JavaScript
cy.get('.target-item').prevAll().each(($el) => {
    cy.wrap($el).should('have.class', 'expected-class');
});
  • cy.get('.target-item') selects the target element.
  • .prevAll() selects all preceding siblings.
  • .each() iterates over each preceding element.
  • cy.wrap($el).should('have.class', 'expected-class') asserts that each preceding element has the expected class.

3. Performing Actions Based on Previous Elements' Content

You need to perform actions such as clicking or verifying states based on the content or attributes of preceding elements. For example, you may want to click a button only if all preceding items have a specific attribute.

Example:

JavaScript
cy.get('.target-item').prevAll().each(($el) => {
    cy.wrap($el).should('have.attr', 'data-status', 'completed');
}).then(() => {
    cy.get('.target-item').click();
});
  • cy.get('.target-item') selects the target element.
  • .prevAll() selects all preceding siblings.
  • .each() iterates over each preceding element and asserts that they have a specific attribute.
  • .then() ensures that the target item is clicked only after all preceding items meet the criteria.

4. Validating Sequential Data Entries

In forms or data tables where entries are sequential, you may need to ensure that preceding data rows or fields meet certain criteria before validating or interacting with a particular row or field.

Example:

JavaScript
cy.get('.target-row').prevAll().each(($row) => {
    cy.wrap($row).find('.status').should('have.text', 'Completed');
});
  • cy.get('.target-row') selects the target row or entry.
  • .prevAll() selects all preceding rows or entries.
  • .each() iterates over each preceding row and asserts that a specific status is displayed.

5. Testing Dynamic Lists or Items

When dealing with dynamically generated lists where items can be added or removed, you might need to check that all preceding items have been correctly updated or are in the expected state before validating a newly added item.

Example:

JavaScript
cy.get('.new-item').prevAll().should('have.length.greaterThan', 0);
  • cy.get('.new-item') selects the newly added item.
  • .prevAll() selects all preceding items.
  • should('have.length.greaterThan', 0) asserts that there are preceding items present before the new item.

Syntax of the prevAll() Method in Cypress

The prevAll() method in Cypress is used to select all preceding siblings of a given element within the same parent. It allows you to traverse backwards in the DOM from a specified element to interact with or validate earlier siblings.

Basic Syntax:

JavaScript
cy.get('selector').prevAll([filter])
  • cy.get('selector'): This command is used to select the element from which you want to find preceding siblings. The selector is a CSS selector that identifies the target element.
  • .prevAll(): Selects all preceding siblings of the target element.
  • [filter] (optional): A CSS selector used to filter the preceding siblings. Only elements matching this selector will be included in the results.

Combining prevAll() with Other Cypress Commands

The prevAll() method can be combined with other Cypress commands to perform more specific queries and actions. Here’s how you can use it effectively:

1. Verifying Content or State of Preceding Siblings

After selecting all preceding siblings of .target-item, this command asserts that each of them has the class expected-class.

JavaScript
cy.get('.target-item').prevAll().should('have.class', 'expected-class');

2. Iterating Over Preceding Siblings

This selects all preceding siblings and iterates over each one to assert that they are visible.

JavaScript
cy.get('.target-item').prevAll().each(($el) => {
    cy.wrap($el).should('be.visible');
});

3. Performing Actions Based on Preceding Siblings

This selects all preceding siblings with the class button, then interacts with the first one by simulating a click.

JavaScript
cy.get('.target-item').prevAll('.button').first().click();

4. Combining with Other Traversal Methods

This selects all preceding siblings of .target-item, then finds input elements within those siblings and asserts that they are checked.

JavaScript
cy.get('.target-item').prevAll().find('input').should('be.checked');

5. Using prevAll() with then() for Custom Assertions

After selecting all preceding siblings, this command uses then() to perform a custom assertion, checking that there are more than two preceding siblings.

JavaScript
cy.get('.target-item').prevAll().then((siblings) => {
    expect(siblings).to.have.length.greaterThan(2);
});

Arguments of the prevAll() Method in Cypress

The prevAll() method in Cypress optionally takes a selector argument that helps filter the preceding siblings of a specified element. This feature allows you to narrow down the selection to only those siblings that match a specific criteria.

Syntax:

JavaScript
cy.get('selector').prevAll([filter])

selector:

  • This is the CSS selector used to identify the target element from which you want to find preceding siblings.
  • Example: cy.get('.target-item') selects the element with class target-item.

[filter] (optional):

  • This is a CSS selector used to filter the preceding siblings.
  • Only those siblings that match the filter criteria will be included in the results.
  • Example: .prevAll('.special-class') will select only those preceding siblings that have the class special-class.

How the Selector Argument Helps:

1. Narrowing Down Results:

  • By providing a selector, you can limit the preceding siblings to those that meet specific criteria. This helps in focusing on a subset of siblings rather than all preceding siblings.
  • Example: If you have multiple preceding siblings and only want to interact with or validate those that have a certain class, using the selector argument makes this straightforward.

2. Targeted Validations:

  • When you only need to check certain preceding siblings, such as elements with a specific attribute or class, the selector argument ensures that only relevant elements are included in the query.
  • Example: To validate only those preceding siblings that are buttons, you can use .prevAll('button') to focus only on button elements.

3. Efficient Testing:

  • Filtering preceding siblings with a selector can make tests more efficient by reducing the number of elements to iterate over or validate. This can be particularly useful in dynamic or large DOM structures.
  • Example: Instead of iterating over all preceding siblings, you can directly select those with a specific attribute, streamlining your test logic.

Example Usage:

1. Basic Usage Without Filter:

This selects all preceding siblings of the element with class target-item.

JavaScript
cy.get('.target-item').prevAll();

2. Using Filter to Narrow Down Results:

This selects only those preceding siblings of the target-item that have the class special-class.

JavaScript
cy.get('.target-item').prevAll('.special-class');

3. Example with Attribute Selector:

This selects all preceding siblings of the target-item that have a data-status attribute with the value completed.

JavaScript
cy.get('.target-item').prevAll('[data-status="completed"]');

Example 1: Simple Case - Validate All Preceding Sibling Elements

You have a list of items and you want to validate that all preceding items have a specific class.

HTML:

HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Example 1 - Validate Siblings</title>
</head>
<body>
    <ul>
        <li class="item active">Item 1</li>
        <li class="item active">Item 2</li>
        <li class="item active">Item 3</li>
        <li class="item target">Item 4</li>
    </ul>
</body>
</html>

Cypress Test:

JavaScript
describe('Validate Preceding Sibling Elements', () => {
    it('should ensure all preceding siblings have the class "active"', () => {
        cy.visit('prev1.html'); // Update this with the correct path
        cy.get('.target').prevAll().should('have.class', 'active');
    });
});
  • cy.get('.target') selects the element with the class target.
  • .prevAll() selects all preceding siblings of the .target element.
  • should('have.class', 'active') asserts that each preceding sibling has the class active.

Output:

prev1
Output

Example 2: Complex Case - Filter Specific Preceding Siblings

You have a list of items with different classes, and you want to filter preceding siblings to validate their attributes and perform actions based on those attributes.

HTML:

HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Example 2 - Filter and Validate Siblings</title>
</head>
<body>
    <ul>
        <li class="item" data-status="completed">Item 1</li>
        <li class="item" data-status="pending">Item 2</li>
        <li class="item" data-status="completed">Item 3</li>
        <li class="item target" data-status="pending">Item 4</li>
    </ul>
</body>
</html>

Cypress Test:

JavaScript
describe('Filter and Validate Specific Preceding Siblings', () => {
    it('should check that all preceding siblings with data-status "completed" are visible', () => {
        cy.visit('prev2.html'); // Update this with the correct path
        cy.get('.target').prevAll('[data-status="completed"]').should('be.visible');
    });

    it('should click the first preceding sibling with data-status "completed"', () => {
        cy.visit('prev2.html'); // Update this with the correct path
        cy.get('.target').prevAll('[data-status="completed"]').first().click();
    });
});
  • cy.get('.target') selects the element with the class target.
  • .prevAll('[data-status="completed"]') filters preceding siblings to include only those with the data-status attribute set to completed.
  • should('be.visible') asserts that these filtered siblings are visible.
  • .first().click() selects the first filtered sibling and simulates a click.

Output:

prev2
Output

Conclusion

The prevAll() method in Cypress provides an optional selector argument that allows you to filter the preceding siblings of a specified element. This filtering capability helps in narrowing down the elements retrieved, making it easier to perform targeted validations, interactions, and assertions on relevant preceding siblings. Whether you're focusing on specific classes, attributes, or types of elements, the selector argument enhances the precision and efficiency of your Cypress tests.


Next Article

Similar Reads