{"id":28218143,"url":"https://github.com/bosniankicks/stealthwright","last_synced_at":"2026-02-27T05:39:31.341Z","repository":{"id":289401205,"uuid":"971136318","full_name":"bosniankicks/stealthwright","owner":"bosniankicks","description":"javascript undetected automation, based on playwright without the detection","archived":false,"fork":false,"pushed_at":"2025-06-03T13:34:38.000Z","size":38,"stargazers_count":13,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-11T04:39:42.723Z","etag":null,"topics":["akamai","antibot","automation","browser","browserautomation","cdp","cloudflare","datadome","incapsula","kasada","playwright","puppeteer","selenium","shape","undetected"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/stealthwright","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bosniankicks.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-23T04:27:28.000Z","updated_at":"2025-06-06T13:50:36.000Z","dependencies_parsed_at":"2025-04-23T04:45:29.973Z","dependency_job_id":"56c92b8f-50a9-4309-9479-32254db54e5d","html_url":"https://github.com/bosniankicks/stealthwright","commit_stats":null,"previous_names":["bosniankicks/stealthwright"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bosniankicks/stealthwright","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bosniankicks%2Fstealthwright","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bosniankicks%2Fstealthwright/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bosniankicks%2Fstealthwright/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bosniankicks%2Fstealthwright/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bosniankicks","download_url":"https://codeload.github.com/bosniankicks/stealthwright/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bosniankicks%2Fstealthwright/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261967131,"owners_count":23237663,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["akamai","antibot","automation","browser","browserautomation","cdp","cloudflare","datadome","incapsula","kasada","playwright","puppeteer","selenium","shape","undetected"],"created_at":"2025-05-18T01:10:23.291Z","updated_at":"2026-02-27T05:39:26.320Z","avatar_url":"https://github.com/bosniankicks.png","language":"JavaScript","readme":"# Stealthwright\n\nStealthwright is a browser automation library with a Playwright-like API using the Chrome DevTools Protocol (CDP) for improved detection avoidance.\n\n## Features\n\n- **Playwright-compatible API**: Familiar syntax for easy migration from Playwright\n- **Detection Avoidance**: Custom CDP implementation for better evasion of anti-bot measures\n- **Human-like Interaction**: Simulate realistic typing with mistakes, natural pauses, and mouse movements\n- **Proxy Support**: Built-in proxy rotation and authentication handling\n- **Cookie Management**: Save and load cookies for session persistence\n- **Headful/Headless Support**: Run with or without visible browser windows\n\n## Installation\n\n```bash\nnpm install stealthwright\n```\n\n## Quick Start\n\n```javascript\nconst { stealthwright } = require('stealthwright');\n\n(async () =\u003e {\n  // Launch a browser\n  const browser = await stealthwright().launch({\n    headless: false,\n  });\n  \n  // Create a browser context\n  const context = browser.defaultBrowserContext();\n  \n  // Open a new page\n  const page = await context.newPage();\n  \n  // Navigate to a URL\n  await page.goto('https://example.com');\n  \n  // Take a screenshot\n  await page.screenshot({ path: 'example.png' });\n  \n  // Close the browser\n  await browser.close();\n})();\n```\n\n## API Overview\n\nStealthwright mimics Playwright's API structure, so if you're familiar with Playwright, you'll feel right at home.\n\n### Browser Management\n\n```javascript\n// Launch a browser\nconst browser = await stealthwright().launch({\n  headless: false,                // Run in visible mode\n  proxy: 'http://user:pass@host:port',  // Use a proxy\n  startURL: 'https://example.com',      // Initial URL\n  ignoreHTTPSErrors: true              // Ignore SSL errors\n});\n\n// Connect to an existing browser\nconst browser = await stealthwright().connect({\n  wsEndpoint: 'ws://localhost:9222/devtools/browser/...'\n});\n\n// Close browser\nawait browser.close();\n```\n\n### Page Actions\n\n```javascript\n// Navigation\nawait page.goto('https://example.com');\nawait page.goBack();\nawait page.goForward();\nawait page.reload();\n\n// Interaction\nawait page.click('#button');\nawait page.fill('#input', 'text');\nawait page.type('#input', 'text', { delay: 100 });\nawait page.typeWithMistakes('#input', 'text', { mistakeProbability: 0.2 });\nawait page.press('#input', 'Enter');\nawait page.setChecked('#checkbox', true);\nawait page.selectOption('#select', 'option1');\nawait page.hover('#element');\n\n// Evaluation\nconst text = await page.textContent('#element');\nconst value = await page.evaluate(() =\u003e document.title);\nconst exists = await page.isVisible('#element');\n```\n\n### Locator Pattern\n\nYou can also use the locator pattern, which is helpful for repeated interactions with the same element:\n\n```javascript\nconst inputField = page.locator('#input');\nawait inputField.fill('text');\nawait inputField.press('Enter');\nconst text = await inputField.textContent();\n```\n\n### Waiting\n\n```javascript\n// Wait for elements\nawait page.waitForSelector('#element');\nawait page.waitForSelector('#element', { state: 'visible' });\n\n// Wait for navigation\nawait page.waitForNavigation();\nawait page.waitForNavigation({ waitUntil: 'networkidle0' });\n\n// Wait for a specific condition\nawait page.waitForFunction(() =\u003e window.status === 'ready');\n\n// Wait for a specific amount of time\nawait page.waitForTimeout(1000); // 1 second\n```\n\n### Screenshots and Content\n\n```javascript\n// Take a screenshot\nawait page.screenshot({ path: 'screenshot.png' });\nawait page.screenshot({ path: 'fullpage.png', fullPage: true });\n\n// Get page content\nconst html = await page.content();\nconst title = await page.title();\n```\n\n### Cookies\n\n```javascript\n// Get all cookies\nconst cookies = await page.cookies();\n\n// Set cookies\nawait page.setCookies([\n  { name: 'cookie1', value: 'value1', domain: 'example.com', path: '/' }\n]);\n\n// Delete cookies\nawait page.deleteCookies();\n\n// Save cookies to file\nawait page.saveCookies('cookies.json');\n\n// Load cookies from file\nawait page.loadCookies('cookies.json');\n```\n\n## Advanced Features\n\n### Human-like Typing\n\nStealthwright can simulate human typing with realistic mistakes:\n\n```javascript\n// Type with random mistakes that are corrected\nawait page.typeWithMistakes('#username', 'example@email.com', {\n  delay: 100, // Time between keypresses in ms\n  mistakeProbability: 0.3 // Probability of making a typing mistake\n});\n```\n\n### Proxy Authentication\n\n```javascript\nconst browser = await stealthwright().launch({\n  proxy: 'http://username:password@proxy-host:port',\n});\n```\n\n### Direct CDP Access\n\n```javascript\n// Execute CDP commands directly\nconst result = await page.cdp('Runtime.evaluate', {\n  expression: 'document.title',\n  returnByValue: true\n});\n```\n\n## Browser Context\n\nBrowser contexts provide an isolated environment similar to incognito mode:\n\n```javascript\n// Create a browser context\nconst context = browser.defaultBrowserContext();\n\n// Create a page in the context\nconst page = await context.newPage();\n\n// Close the context when done\nawait context.close();\n```\n\n## Error Handling\n\n```javascript\ntry {\n  await page.click('#non-existent-element');\n} catch (error) {\n  if (error instanceof TimeoutError) {\n    console.log('Element not found within timeout period');\n  } else {\n    console.error('Unexpected error:', error);\n  }\n}\n```\n\n## Examples\n\n### Login to a Website\n\n```javascript\nconst { stealthwright } = require('stealthwright');\nconst fs = require('fs');\n\n(async () =\u003e {\n  const browser = await stealthwright().launch({ headless: false });\n  const context = browser.defaultBrowserContext();\n  const page = await context.newPage();\n  \n  try {\n    // Navigate to login page\n    await page.goto('https://example.com/login');\n    \n    // Fill in the login form\n    await page.fill('#username', 'user@example.com');\n    await page.fill('#password', 'password123');\n    \n    // Click the login button\n    await page.click('#login-button');\n    \n    // Wait for navigation\n    await page.waitForNavigation();\n    \n    // Save cookies for future sessions\n    await page.saveCookies('auth-cookies.json');\n    \n    console.log('Login successful!');\n  } catch (error) {\n    console.error('Login failed:', error);\n  } finally {\n    await browser.close();\n  }\n})();\n```\n\n### Scraping Data\n\n```javascript\nconst { stealthwright } = require('stealthwright');\nconst fs = require('fs');\n\n(async () =\u003e {\n  const browser = await stealthwright().launch();\n  const page = await browser.defaultBrowserContext().newPage();\n  \n  try {\n    await page.goto('https://example.com/products');\n    \n    // Extract product information\n    const products = await page.evaluate(() =\u003e {\n      return Array.from(document.querySelectorAll('.product')).map(product =\u003e ({\n        title: product.querySelector('.title').textContent,\n        price: product.querySelector('.price').textContent,\n        url: product.querySelector('a').href\n      }));\n    });\n    \n    // Save the data\n    fs.writeFileSync('products.json', JSON.stringify(products, null, 2));\n    console.log(`Scraped ${products.length} products`);\n  } catch (error) {\n    console.error('Scraping failed:', error);\n  } finally {\n    await browser.close();\n  }\n})();\n```\n\n## Comparison with Playwright\n\nStealthwright provides a similar API to Playwright but with enhanced detection avoidance:\n\n```javascript\n// Playwright:\nconst { chromium } = require('playwright');\nconst browser = await chromium.launch();\n\n// stealthwright:\nconst { stealthwright } = require('stealthwright');\nconst browser = await stealthwright().launch();\n\n// The rest of your code can remain almost identical\n```\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbosniankicks%2Fstealthwright","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbosniankicks%2Fstealthwright","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbosniankicks%2Fstealthwright/lists"}