PracHub
QuestionsCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates implementation skills for a simplified selector engine, DOM traversal and manipulation, wildcard attribute pattern matching, and ordered string reconstruction from element attributes.

  • medium
  • Ramp
  • Coding & Algorithms
  • Software Engineer

Implement wildcard querySelector to extract URL

Company: Ramp

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Take-home Project

## Problem: Extract a hidden URL from a deeply nested DOM A webpage hides a URL by splitting it into individual characters stored in DOM elements. The DOM structure is deeply nested, and you are **not allowed to use** the browser’s built-in `querySelector/querySelectorAll`. You must implement a simplified selector engine and use it to locate the hidden characters. ### DOM snippet (example) ```html <section data-id="23*"> <article data-class="*45"> <div data-tag="*78*"> <b class="ref" value="h"></b> <b class="ref" value="t"></b> <b class="ref" value="t"></b> <b class="ref" value="p"></b> <!-- ...more <b> nodes each holding one character... --> </div> </article> </section> ``` ### Selector syntax you must support Implement: ```js function querySelectorAll(root, selector) { /* ... */ } ``` Where `selector` is a **descendant chain** separated by spaces, e.g. ``` section[data-id="23*"] article[data-class="*45"] div[data-tag="*78*"] b.ref ``` Each segment may contain: - a **tag name** (e.g., `section`, `div`, `b`) - **at most one class** (e.g., `.ref`) - **at most one attribute filter** like `[data-id="PATTERN"]` Attribute filter patterns may include `*` wildcards: - `*` matches **any string (including empty)** - Examples: - `"23*"` matches `"23"`, `"230"`, `"23abc"` - `"*45"` matches `"45"`, `"abc45"` - `"*78*"` matches `"78"`, `"a78b"`, `"xx78"` ### Task 1. Implement `querySelectorAll(root, selector)` to return all matching elements in **document order**. 2. Use it to find all matching `<b class="ref">` nodes and reconstruct the URL by concatenating each node’s `value` attribute in order. ### Output Return the reconstructed URL as a string. ### Constraints / assumptions - The DOM is a tree of elements with `tagName`, `getAttribute(name)`, `classList`, and `children` (or equivalent). - No commas, `>`, `+`, `:nth-child`, or other CSS features—only the subset described above. - The hidden URL characters appear in the correct order in the DOM traversal order under the matched container.

Quick Answer: This question evaluates implementation skills for a simplified selector engine, DOM traversal and manipulation, wildcard attribute pattern matching, and ordered string reconstruction from element attributes.

Part 1: Simplified Wildcard querySelectorAll

You are given a DOM-like tree encoded as arrays. Implement a simplified selector engine that returns all nodes matching a descendant selector chain in document order. A selector is split into space-separated segments. Each segment may include an optional tag name, at most one class such as `.ref`, and at most one attribute filter such as `[data-id="23*"]`. Attribute patterns may contain `*`, which matches any string, including the empty string. The first segment may match the root or any descendant. Each later segment must match a proper descendant of an element that satisfied the previous segment.

Constraints

  • 0 <= number of nodes <= 10000
  • If the tree is non-empty, 0 <= root < number of nodes
  • `children` forms a valid rooted tree, and children are listed in document order
  • Selector contains 1 to 20 space-separated segments, unless the tree is empty
  • Each segment has optional tag, optional one class, and optional one attribute filter
  • Attribute wildcard `*` matches any string, including empty

Examples

Input: (['document', 'section', 'article', 'div', 'b', 'b', 'span'], [[], [], [], [], ['ref'], ['ref'], ['ref']], [[], [['data-id', '23abc']], [['data-class', 'abc45']], [['data-tag', 'x78y']], [['value', 'h']], [['value', 'i']], [['value', '!']]], [[1], [2], [3], [4, 5, 6], [], [], []], 0, 'section[data-id="23*"] article[data-class="*45"] div[data-tag="*78*"] b.ref')

Expected Output: [4, 5]

Explanation: The section, article, and div match the wildcard attribute filters. Nodes 4 and 5 are matching b.ref descendants; node 6 has class ref but tag span.

Input: (['root', 'div', 'section', 'p', 'span', 'span'], [[], ['box'], [], [], ['target'], ['target']], [[], [['role', 'main']], [], [], [['data-code', 'AB']], [['data-code', 'CAB']]], [[1, 5], [2], [3], [4], [], []], 0, 'div.box span[data-code="*AB"]')

Expected Output: [4]

Explanation: Only node 4 is a descendant of the div.box node. Node 5 matches the segment but is not under that div.

Input: (['div', 'div', 'div', 'p'], [[], [], [], []], [[], [], [], []], [[1, 3], [2], [], []], 0, 'div div')

Expected Output: [1, 2]

Explanation: Node 1 is a div descendant of node 0. Node 2 is also a div with at least one div ancestor. Each result appears once.

Input: ([], [], [], [], -1, 'b.ref')

Expected Output: []

Explanation: An empty tree has no matching nodes.

Input: (['root', 'item', 'item'], [[], [], []], [[], [['data-id', '']], [['data-id', 'x']]], [[1, 2], [], []], 0, 'item[data-id="*"]')

Expected Output: [1, 2]

Explanation: The wildcard pattern * matches both the empty string and non-empty strings.

Hints

  1. Parse each selector segment into three checks: tag, class, and attribute pattern.
  2. During a preorder traversal, keep track of which selector prefixes have already matched among the current node's ancestors.

Part 2: Reconstruct Hidden URL from Matched DOM Nodes

A hidden URL is stored one character at a time in DOM nodes. Each matching node has a `value` attribute containing one character. Given the same DOM encoding and simplified selector syntax from Part 1, find all nodes matching the selector in document order, then concatenate their `value` attributes to reconstruct the hidden URL. You may not rely on a built-in selector engine; your function must perform the simplified matching itself.

Constraints

  • 0 <= number of nodes <= 10000
  • If the tree is non-empty, 0 <= root < number of nodes
  • `children` forms a valid rooted tree, and children are listed in document order
  • Selector contains 1 to 20 space-separated segments, unless the tree is empty
  • Each selected URL character node usually has a `value` attribute containing one character
  • Attribute wildcard `*` matches any string, including empty

Examples

Input: (['document', 'section', 'article', 'div', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b'], [[], [], [], [], ['other'], ['ref'], ['ref'], ['ref'], ['ref'], ['ref'], ['ref'], ['ref'], ['ref'], ['ref'], ['ref'], ['ref'], ['ref']], [[], [['data-id', '23abc']], [['data-class', 'z45']], [['data-tag', 'x78z']], [['value', '!']], [['value', 'h']], [['value', 't']], [['value', 't']], [['value', 'p']], [['value', 's']], [['value', ':']], [['value', '/']], [['value', '/']], [['value', 'x']], [['value', '.']], [['value', 'i']], [['value', 'o']]], [[1], [2], [3], [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []], 0, 'section[data-id="23*"] article[data-class="*45"] div[data-tag="*78*"] b.ref')

Expected Output: 'https://x.io'

Explanation: The decoy b node has class other and is ignored. The remaining matching b.ref nodes provide the URL characters in order.

Input: (['root', 'div', 'b', 'span', 'b', 'div', 'b', 'b'], [[], [], ['ref'], [], ['ref'], [], ['ref'], ['ref']], [[], [['data-kind', 'url-main']], [['value', 'g']], [], [['value', 'o']], [['data-kind', 'url-extra']], [['value', '.']], [['value', 'd']]], [[1, 5], [2, 3, 4], [], [], [], [6, 7], [], []], 0, 'div[data-kind="url*"] b.ref')

Expected Output: 'go.d'

Explanation: Both div containers match `url*`, so all b.ref descendants under them are concatenated in document order.

Input: (['b'], [['ref']], [[['value', 'Z']]], [[]], 0, 'b.ref')

Expected Output: 'Z'

Explanation: The root itself is allowed to match the first selector segment.

Input: (['root', 'div', 'b'], [[], [], ['other']], [[], [['data-kind', 'not-url']], [['value', 'x']]], [[1], [2], []], 0, 'div[data-kind="url*"] b.ref')

Expected Output: ''

Explanation: No container matches the required attribute pattern, so the reconstructed string is empty.

Input: ([], [], [], [], -1, 'b.ref')

Expected Output: ''

Explanation: An empty tree reconstructs to an empty string.

Hints

  1. First solve the selector-matching problem; reconstruction is then just a document-order concatenation.
  2. Use preorder traversal because document order for a tree is parent before children, with children visited from left to right.
Last updated: Jul 7, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Find User Airport at a Time - Ramp (medium)
  • Find an Exit in a URL Maze - Ramp (medium)
  • Maximize Earnings by Converting Days Off into Workdays - Ramp (medium)
  • Minimum Character Changes to Make Every k-Length Block a Palindrome - Ramp (medium)
  • Maximum Profit from Dated Stock Trade Records - Ramp (medium)