Bird
Raised Fist0
Cypresstesting~15 mins

cy.parent() and cy.children() in Cypress - Deep Dive

Choose your learning style10 modes available
Overview - cy.parent() and cy.children()
What is it?
In Cypress, cy.parent() and cy.children() are commands used to navigate the HTML structure of a web page during testing. cy.parent() selects the immediate parent element of the current element, while cy.children() selects all direct child elements of the current element. These commands help testers find and interact with related elements in the page's structure.
Why it matters
Web pages are built like nested boxes, where elements contain other elements. To test how parts of a page behave, you often need to move up or down this nesting. Without commands like cy.parent() and cy.children(), testers would struggle to locate elements related by structure, making tests fragile and hard to write. These commands make tests clearer, more reliable, and easier to maintain.
Where it fits
Before learning cy.parent() and cy.children(), you should understand basic Cypress commands like cy.get() to select elements. After mastering these, you can learn more advanced traversal commands like cy.closest() or cy.siblings(), and then move on to writing complex user interaction tests.
Mental Model
Core Idea
cy.parent() moves one step up the element tree, and cy.children() moves one step down to direct descendants, letting you navigate the page structure easily.
Think of it like...
Imagine a family tree: cy.parent() is like asking 'Who is my parent?' and cy.children() is like asking 'Who are my children?'. This helps you find relatives nearby in the family.
Element Tree Navigation

Current Element
   │
   ├─ cy.parent() → Immediate Parent Element
   │
   └─ cy.children() → All Direct Child Elements

Example:
<div>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
  </ul>
</div>

If current element is <li>, cy.parent() selects <ul>, cy.children() on <ul> selects all <li> elements.
Build-Up - 7 Steps
1
FoundationUnderstanding DOM Element Relationships
🤔
Concept: Learn what parent and child elements mean in a web page's structure.
Every web page is made of elements nested inside each other. The element that contains another is called the parent, and the elements inside it are children. For example, a
    (unordered list) is the parent of its
  • (list item) children.
Result
You can identify which elements are parents and which are children in the page's HTML.
Understanding the parent-child relationship is the foundation for navigating and testing web page elements effectively.
2
FoundationSelecting Elements with cy.get()
🤔
Concept: Learn how to select elements on the page using Cypress's basic command.
cy.get('selector') finds elements matching the selector. For example, cy.get('ul') selects all unordered lists on the page. This is the starting point before moving up or down the element tree.
Result
You can select elements to work with in your tests.
Knowing how to select elements is essential before you can navigate their relationships.
3
IntermediateUsing cy.parent() to Move Up the Tree
🤔Before reading on: do you think cy.parent() selects all ancestors or just the immediate parent? Commit to your answer.
Concept: cy.parent() selects only the immediate parent element of the current element.
If you have selected a child element, calling cy.parent() moves one step up to its direct parent. For example, cy.get('li').parent() selects the
    that contains the list item.
Result
Tests can target the container or wrapper element of a selected element.
Knowing that cy.parent() only moves one level up prevents confusion and helps write precise tests.
4
IntermediateUsing cy.children() to Move Down the Tree
🤔Before reading on: do you think cy.children() selects all descendants or only direct children? Commit to your answer.
Concept: cy.children() selects all direct child elements of the current element, not deeper descendants.
If you select a parent element, calling cy.children() returns all elements directly inside it. For example, cy.get('ul').children() returns all
  • elements inside the list.
  • Result
    Tests can easily find all immediate child elements to check or interact with.
    Understanding that cy.children() does not go deeper than direct children helps avoid unexpected test results.
    5
    IntermediateFiltering with cy.parent() and cy.children()
    🤔Before reading on: can you chain cy.children() with a selector to get specific children? Commit to your answer.
    Concept: You can filter the elements returned by cy.parent() or cy.children() by passing a selector to narrow down results.
    For example, cy.get('li').parent('ul.special') selects the parent only if it matches the selector 'ul.special'. Similarly, cy.get('ul').children('li.active') selects only child
  • elements with class 'active'.
  • Result
    Tests become more precise by targeting specific related elements.
    Filtering traversal results helps write focused tests that avoid false positives.
    6
    AdvancedCombining cy.parent() and cy.children() for Complex Traversal
    🤔Before reading on: do you think chaining cy.parent() and cy.children() can select siblings? Commit to your answer.
    Concept: By chaining cy.parent() and cy.children(), you can move up to a parent and then down to its children, effectively selecting siblings of the original element.
    Example: cy.get('li.active').parent().children() selects all
  • siblings of the active item. This helps test groups of related elements together.
  • Result
    You can navigate complex element relationships to test groups or related elements.
    Chaining traversal commands unlocks powerful ways to select elements based on their relationships.
    7
    ExpertUnderstanding cy.parent() and cy.children() in Shadow DOM
    🤔Before reading on: do you think cy.parent() and cy.children() work inside Shadow DOM by default? Commit to your answer.
    Concept: Shadow DOM creates isolated parts of the page. cy.parent() and cy.children() do not cross Shadow DOM boundaries unless special handling is used.
    When testing components using Shadow DOM, cy.parent() and cy.children() only traverse within the same shadow root. To access elements outside, you need to use commands like cy.shadow() first.
    Result
    Tests correctly handle modern web components and avoid false failures due to traversal limits.
    Knowing traversal limits with Shadow DOM prevents confusion and helps write robust tests for modern web apps.
    Under the Hood
    Cypress commands like cy.parent() and cy.children() use the browser's native DOM API under the hood. cy.parent() calls the 'parentNode' property to get the immediate parent element, while cy.children() uses 'children' property to get direct child elements. Cypress wraps these native elements in its own chainable objects to allow further commands and assertions.
    Why designed this way?
    The design follows the natural DOM tree structure, which is a standard in web development. Using immediate parent and direct children keeps traversal simple and predictable. Alternatives like selecting all ancestors or all descendants would be more complex and less precise, so Cypress provides separate commands for those cases.
    DOM Traversal Internals
    
    [Current Element]
         │ parentNode
         ▼
    [Parent Element]
         │ children
         ▼
    [Child Elements]
    
    cy.parent() → parentNode property
    cy.children() → children property
    
    Cypress wraps these native elements for chaining.
    Myth Busters - 3 Common Misconceptions
    Quick: Does cy.parent() select all ancestor elements or just one? Commit to your answer.
    Common Belief:cy.parent() selects all ancestors up the tree, not just the immediate parent.
    Tap to reveal reality
    Reality:cy.parent() selects only the immediate parent element, not all ancestors.
    Why it matters:Assuming it selects all ancestors can cause tests to fail or select wrong elements, leading to flaky tests.
    Quick: Does cy.children() select all descendants or only direct children? Commit to your answer.
    Common Belief:cy.children() selects all descendants at any depth, like a deep search.
    Tap to reveal reality
    Reality:cy.children() selects only direct child elements, not deeper descendants.
    Why it matters:Misunderstanding this can cause tests to miss elements or select too many, making assertions unreliable.
    Quick: Do cy.parent() and cy.children() cross Shadow DOM boundaries automatically? Commit to your answer.
    Common Belief:They work the same inside and outside Shadow DOM without extra steps.
    Tap to reveal reality
    Reality:They do not cross Shadow DOM boundaries unless you explicitly handle shadow roots with cy.shadow().
    Why it matters:Ignoring Shadow DOM limits causes tests to fail silently or select wrong elements in modern web apps.
    Expert Zone
    1
    cy.parent() returns only one element even if multiple elements are in the chain, which can affect chaining behavior.
    2
    cy.children() returns all direct children, but you can filter them with selectors to improve test precision.
    3
    Traversal commands do not retry automatically like cy.get(); understanding this helps avoid flaky tests when elements change dynamically.
    When NOT to use
    Avoid using cy.parent() or cy.children() when you need to select all ancestors or all descendants at any depth; instead, use cy.parents() or cy.find(). Also, for Shadow DOM traversal, use cy.shadow() before these commands.
    Production Patterns
    In real-world tests, cy.parent() and cy.children() are often combined with filters and assertions to verify UI structure, such as checking if a button is inside a specific container or if a list has the expected items. They help keep selectors resilient to layout changes by relying on structure rather than fixed IDs.
    Connections
    Tree Data Structures
    cy.parent() and cy.children() mimic navigating nodes in a tree structure.
    Understanding tree traversal in computer science helps grasp how these commands move up and down the DOM tree.
    File System Navigation
    Moving between parent and child directories is similar to cy.parent() and cy.children() moving between elements.
    Knowing how to navigate folders helps understand element traversal commands intuitively.
    Family Relationships
    Parent and child elements relate like family members, with direct connections.
    This connection helps remember the immediate relationship focus of these commands.
    Common Pitfalls
    #1Assuming cy.parent() selects all ancestor elements.
    Wrong approach:cy.get('li').parent().should('have.class', 'container') // expects any ancestor with class 'container'
    Correct approach:cy.get('li').parents('.container').should('exist') // selects all ancestors matching selector
    Root cause:Confusing cy.parent() with cy.parents(), leading to wrong element selection.
    #2Using cy.children() expecting to select all nested descendants.
    Wrong approach:cy.get('div').children('span').should('have.length', 5) // expects all nested spans
    Correct approach:cy.get('div').find('span').should('have.length', 5) // selects all descendants at any depth
    Root cause:Misunderstanding that cy.children() only selects direct children, not deep descendants.
    #3Trying to traverse outside Shadow DOM without cy.shadow().
    Wrong approach:cy.get('custom-element').parent() // expects parent outside shadow root
    Correct approach:cy.get('custom-element').shadow().parent() // accesses parent inside shadow root
    Root cause:Not accounting for Shadow DOM boundaries in traversal commands.
    Key Takeaways
    cy.parent() selects only the immediate parent element of the current element in the DOM tree.
    cy.children() selects all direct child elements of the current element, not deeper descendants.
    These commands help navigate the page structure to write clearer and more reliable tests.
    Understanding their behavior prevents common mistakes like selecting wrong elements or missing targets.
    In modern web apps with Shadow DOM, special handling is needed to traverse inside shadow roots.

    Practice

    (1/5)
    1. What does the Cypress command cy.parent() do?
    easy
    A. Finds all child elements of the current element
    B. Finds the immediate parent element of the current element
    C. Finds all sibling elements of the current element
    D. Finds the first child element of the current element

    Solution

    1. Step 1: Understand the purpose of cy.parent()

      This command is used to get the immediate parent of the currently selected element in the DOM tree.
    2. Step 2: Compare with other options

      cy.children() finds children, siblings are not targeted by cy.parent(), and it does not find the first child specifically.
    3. Final Answer:

      Finds the immediate parent element of the current element -> Option B
    4. Quick Check:

      cy.parent() = immediate parent [OK]
    Hint: Parent means one level up in the DOM tree [OK]
    Common Mistakes:
    • Confusing parent with children
    • Thinking it finds all ancestors
    • Assuming it finds siblings
    2. Which of the following is the correct syntax to get all direct children of an element with class container in Cypress?
    easy
    A. cy.get('.container').children()
    B. cy.get('.container').parent()
    C. cy.get('.container').child()
    D. cy.get('.container').parents()

    Solution

    1. Step 1: Identify the correct command for children

      The command to get direct children is children(), so cy.get('.container').children() is correct.
    2. Step 2: Check other options for correctness

      parent() gets the parent, child() is not a valid Cypress command, and parents() gets all ancestors, not children.
    3. Final Answer:

      cy.get('.container').children() -> Option A
    4. Quick Check:

      children() gets direct children [OK]
    Hint: Use children() to get direct children elements [OK]
    Common Mistakes:
    • Using parent() instead of children()
    • Using incorrect method child()
    • Confusing parents() with children()
    3. Consider the following HTML structure:
    <div class='grandparent'>
      <div class='parent'>
        <span class='child'>Hello</span>
        <span class='child'>World</span>
      </div>
    </div>

    What will cy.get('.child').parent().should('have.class', 'parent') assert?
    medium
    A. That the grandparent has class 'parent'
    B. That the children of .parent have class 'child'
    C. That the parent of each .child element has class 'parent'
    D. That the .child elements have class 'parent'

    Solution

    1. Step 1: Understand the command chain

      cy.get('.child') selects both span elements. parent() gets their immediate parent, which is the div with class 'parent'.
    2. Step 2: Analyze the assertion

      The assertion checks if the parent element has class 'parent', which is true for both .child elements.
    3. Final Answer:

      That the parent of each .child element has class 'parent' -> Option C
    4. Quick Check:

      parent() gets immediate parent with class 'parent' [OK]
    Hint: parent() gets immediate parent element of selected children [OK]
    Common Mistakes:
    • Thinking parent() gets grandparent
    • Confusing children with parent
    • Assuming assertion checks children classes
    4. You wrote this Cypress test:
    cy.get('.list').children('.item').parent('.container')

    But it fails with an error. What is the likely cause?
    medium
    A. The parent() command does not accept a selector argument
    B. The children() command cannot filter by class
    C. The parent() command returns all ancestors, not immediate parent
    D. The children() command returns siblings, not children

    Solution

    1. Step 1: Check parent() usage

      The parent() command in Cypress does not accept any selector argument; it always returns the immediate parent element.
    2. Step 2: Verify other commands

      children() can filter by selector, so that part is valid. parent() does not return all ancestors, only immediate parent. children() returns direct children, not siblings.
    3. Final Answer:

      The parent() command does not accept a selector argument -> Option A
    4. Quick Check:

      parent() takes no selector argument [OK]
    Hint: parent() never takes a selector; children() can filter [OK]
    Common Mistakes:
    • Passing selector to parent()
    • Confusing children() filtering
    • Thinking parent() returns all ancestors
    5. Given this HTML:
    <ul class='menu'>
      <li class='item'>Home</li>
      <li class='item'>About</li>
      <li class='item'>Contact</li>
    </ul>
    <div class='footer'>Footer content</div>

    Which Cypress command chain correctly selects the <ul> element starting from the <li> elements with class item?
    hard
    A. cy.get('.item').children('ul')
    B. cy.get('.item').parent().parent()
    C. cy.get('.item').children()
    D. cy.get('.item').parent()

    Solution

    1. Step 1: Identify the parent of .item elements

      Each <li class='item'> is a direct child of the <ul class='menu'> element.
    2. Step 2: Use parent() to get immediate parent

      cy.get('.item').parent() correctly gets the immediate parent <ul class='menu'> element.
    3. Step 3: Check other options

      children('ul') is wrong because <li> elements do not have <ul> children. parent().parent() goes too far up. children() gets children, not parent.
    4. Final Answer:

      cy.get('.item').parent() -> Option D
    5. Quick Check:

      parent() gets immediate parent [OK]
    Hint: Use parent() to get immediate parent element [OK]
    Common Mistakes:
    • Using children() to get parent
    • Going two levels up unnecessarily
    • Assuming children() returns parent
    Recommended

    Ready to prove it?

    Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

    10 questions~5 mineasy hard