Implementation:Puppeteer Puppeteer Injected PQuerySelector
| Property | Value |
|---|---|
| sources | packages/puppeteer-core/src/injected/PQuerySelector.ts
|
| domains | Injected Scripts, Query Selectors, P-Selectors |
| last_updated | 2026-02-12 00:00 GMT |
Overview
Description
The PQuerySelector module is the core in-page query engine for Puppeteer's proprietary "P-selector" syntax. P-selectors extend standard CSS selectors with pseudo-element selectors for text (::-p-text), XPath (::-p-xpath), ARIA (::-p-aria), and custom registered handlers. The module also supports deep combinators: >>> (descendent -- pierces all shadow roots) and >>>> (child -- pierces one shadow root level).
The file defines several internal types representing the parsed P-selector AST (CSSSelector, PPseudoSelector, PCombinator, CompoundPSelector, ComplexPSelector, ComplexPSelectorList), the PQueryEngine class that walks the DOM using those parsed selectors, a DepthCalculator for DOM-order sorting, and the exported pQuerySelector / pQuerySelectorAll functions.
Usage
This module runs inside the browser page context. It is invoked by Puppeteer's query handler infrastructure when a user calls APIs such as page.$('selector') or page.$$('selector') with P-selector syntax. The selector string arrives pre-parsed as a JSON-encoded ComplexPSelectorList. Results are returned in DOM order after deduplication.
Code Reference
Source Location
packages/puppeteer-core/src/injected/PQuerySelector.ts (294 lines)
Signature
// Types
export type CSSSelector = string;
export interface PPseudoSelector { name: string; value: string; }
export const enum PCombinator { Descendent = '>>>', Child = '>>>>' }
export type CompoundPSelector = Array<CSSSelector | PPseudoSelector>;
export type ComplexPSelector = Array<CompoundPSelector | PCombinator>;
export type ComplexPSelectorList = ComplexPSelector[];
// Engine
class PQueryEngine {
elements: AwaitableIterable<Node>;
constructor(element: Node, complexSelector: ComplexPSelector);
async run(): Promise<void>;
}
// Exported query functions
export const pQuerySelectorAll: (root: Node, selector: string) => AwaitableIterable<Node>;
export const pQuerySelector: (root: Node, selector: string) => Promise<Node | null>;
Import
import { pQuerySelector, pQuerySelectorAll } from '../injected/PQuerySelector.js';
I/O Contract
pQuerySelectorAll
| Direction | Name | Type | Description |
|---|---|---|---|
| Input | root | Node |
The DOM node to search within |
| Input | selector | string |
JSON-encoded ComplexPSelectorList
|
| Output | result | AwaitableIterable<Node> |
Matching nodes in DOM order, deduplicated |
| Error | Error | Error |
Thrown on contiguous deep combinators or unknown pseudo-selector names |
pQuerySelector
| Direction | Name | Type | Description |
|---|---|---|---|
| Input | root | Node |
The DOM node to search within |
| Input | selector | string |
JSON-encoded ComplexPSelectorList
|
| Output | result | null> | First matching node or null |
Usage Examples
// Internal usage: querying with a P-selector from inside the page context
import { pQuerySelector, pQuerySelectorAll } from '../injected/PQuerySelector.js';
// Find a single element by text content
const selectorJson = JSON.stringify([[{ name: 'text', value: 'Submit' }]]);
const button = await pQuerySelector(document, selectorJson);
// Find all elements matching an ARIA role selector
const ariaJson = JSON.stringify([[{ name: 'aria', value: 'button' }]]);
for await (const el of pQuerySelectorAll(document, ariaJson)) {
console.log(el);
}
// Deep combinator usage: pierce shadow DOM
// Represents "div >>> span" -- find span inside shadow roots under div
const deepJson = JSON.stringify([['div', '>>>', ['span']]]);
const span = await pQuerySelector(document, deepJson);