Skip to content

feat: add isAutomatedBrowser helper to detect automated browsers - #497

Open
aidenybai wants to merge 5 commits into
mainfrom
cursor/add-automated-browser-helper-476c
Open

feat: add isAutomatedBrowser helper to detect automated browsers#497
aidenybai wants to merge 5 commits into
mainfrom
cursor/add-automated-browser-helper-476c

Conversation

@aidenybai

@aidenybai aidenybai commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Summary

Adds an isAutomatedBrowser() utility to react-grab that detects whether the library is running inside an automated/headless browser (Playwright, Puppeteer, Selenium/WebDriver), and uses it to label the version-check telemetry source.

Changes

  1. New util is-automated-browser.ts — detects automated browsers.
  2. log-intro.ts — when fetching the latest version, the request's source query param is now automated-browser instead of browser when an automated browser is detected:
const source = isAutomatedBrowser() ? "automated-browser" : "browser";
fetch(`https://www.react-grab.com/api/version?source=${source}&v=${version}&t=${Date.now()}`, ...)

What it detects

  • Navigator signalnavigator.webdriver === true (W3C-standard flag set by all WebDriver-based tools) and HeadlessChrome in the user agent.
  • Automation globals — Playwright (__playwright__, __pwInitScripts), Puppeteer (__puppeteer__), generic CDP (domAutomation, domAutomationController), and Selenium IDE (_Selenium_IDE_Recorder, _selenium, callSelenium).
  • WebDriver document markers__selenium_unwrapped, __webdriver_evaluate, $cdc_*, etc.

Notes

  • Follows existing util conventions (one util per file, arrow function, memoized result, matching is-mac.ts / is-next-project-runtime.ts).
  • SSR-safe: guards against missing navigator / document.
Open in Web Open in Cursor 

Summary by cubic

Adds isAutomatedBrowser() to react-grab to detect automated/headless browsers and label version-check telemetry. Detection now covers navigator signals, common automation globals, and WebDriver document markers; it’s SSR-safe and memoized.

  • New Features

    • Detects navigator.webdriver, HeadlessChrome UA, automation globals (Playwright/Puppeteer/Selenium), and WebDriver document markers.
    • Sets telemetry source to automated-browser when automation is detected.
  • Refactors

    • Dropped the revalidate option; kept SSR guards and memoization.

Written for commit adf9ec1. Summary will update on new commits.

Review in cubic

…lenium

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
@vercel

vercel Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
react-grab-storybook Ready Ready Preview, Comment Jun 27, 2026 9:01am
react-grab-website Ready Ready Preview, Comment Jun 27, 2026 9:01am

@pkg-pr-new

pkg-pr-new Bot commented Jun 27, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@react-grab/cli@497
npm i https://pkg.pr.new/grab@497
npm i https://pkg.pr.new/react-grab@497

commit: adf9ec1

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/react-grab/src/utils/is-automated-browser.ts">

<violation number="1" location="packages/react-grab/src/utils/is-automated-browser.ts:27">
P2: Hard-coding a single `$cdc_` key misses other ChromeDriver-injected `$cdc_*` markers. Use a prefix scan on document keys to preserve detection coverage.</violation>

<violation number="2" location="packages/react-grab/src/utils/is-automated-browser.ts:36">
P2: Cached detection cannot be revalidated, so `isAutomatedBrowser()` can return a stale false/true for the rest of the session. Match other cached utils by adding an optional `shouldRevalidate` reset path.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

markers.__fxdriver_evaluate ||
markers.__webdriver_script_function ||
// ChromeDriver injects this oddly-named helper array on document.
markers.$cdc_asdjflasutopfhvcZLmcfl_ ||

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Hard-coding a single $cdc_ key misses other ChromeDriver-injected $cdc_* markers. Use a prefix scan on document keys to preserve detection coverage.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/react-grab/src/utils/is-automated-browser.ts, line 27:

<comment>Hard-coding a single `$cdc_` key misses other ChromeDriver-injected `$cdc_*` markers. Use a prefix scan on document keys to preserve detection coverage.</comment>

<file context>
@@ -0,0 +1,40 @@
+      markers.__fxdriver_evaluate ||
+      markers.__webdriver_script_function ||
+      // ChromeDriver injects this oddly-named helper array on document.
+      markers.$cdc_asdjflasutopfhvcZLmcfl_ ||
+      markers.$chrome_asyncScriptInfo,
+  );
</file context>

Comment on lines +36 to +40
export const isAutomatedBrowser = (): boolean => {
cachedIsAutomatedBrowser ??=
hasAutomationNavigatorSignal() || hasAutomationGlobal() || hasWebdriverDocumentMarker();
return cachedIsAutomatedBrowser;
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Cached detection cannot be revalidated, so isAutomatedBrowser() can return a stale false/true for the rest of the session. Match other cached utils by adding an optional shouldRevalidate reset path.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/react-grab/src/utils/is-automated-browser.ts, line 36:

<comment>Cached detection cannot be revalidated, so `isAutomatedBrowser()` can return a stale false/true for the rest of the session. Match other cached utils by adding an optional `shouldRevalidate` reset path.</comment>

<file context>
@@ -0,0 +1,40 @@
+  typeof navigator !== "undefined" &&
+  (navigator.webdriver === true || /HeadlessChrome/i.test(navigator.userAgent));
+
+export const isAutomatedBrowser = (): boolean => {
+  cachedIsAutomatedBrowser ??=
+    hasAutomationNavigatorSignal() || hasAutomationGlobal() || hasWebdriverDocumentMarker();
</file context>
Suggested change
export const isAutomatedBrowser = (): boolean => {
cachedIsAutomatedBrowser ??=
hasAutomationNavigatorSignal() || hasAutomationGlobal() || hasWebdriverDocumentMarker();
return cachedIsAutomatedBrowser;
};
export const isAutomatedBrowser = (shouldRevalidate?: boolean): boolean => {
if (shouldRevalidate) {
cachedIsAutomatedBrowser = undefined;
}
cachedIsAutomatedBrowser ??=
hasAutomationNavigatorSignal() || hasAutomationGlobal() || hasWebdriverDocumentMarker();
return cachedIsAutomatedBrowser;
};

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/react-grab/src/utils/is-automated-browser.ts">

<violation number="1" location="packages/react-grab/src/utils/is-automated-browser.ts:27">
P2: Hard-coding a single `$cdc_` key misses other ChromeDriver-injected `$cdc_*` markers. Use a prefix scan on document keys to preserve detection coverage.</violation>

<violation number="2" location="packages/react-grab/src/utils/is-automated-browser.ts:36">
P2: Cached detection cannot be revalidated, so `isAutomatedBrowser()` can return a stale false/true for the rest of the session. Match other cached utils by adding an optional `shouldRevalidate` reset path.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/react-grab/src/utils/is-automated-browser.ts Outdated
Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants