Merge pull request #20 from amhsirak/develop

feat: stealth (oss)
This commit is contained in:
amhsirak
2024-07-20 18:16:42 +05:30
committed by GitHub
6 changed files with 29 additions and 8 deletions

View File

@@ -4,6 +4,7 @@
"author": "Karishma Shukla", "author": "Karishma Shukla",
"license": "", "license": "",
"dependencies": { "dependencies": {
"@cliqz/adblocker-playwright": "^1.30.0",
"@emotion/react": "^11.9.0", "@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1", "@emotion/styled": "^11.8.1",
"@mui/icons-material": "^5.5.1", "@mui/icons-material": "^5.5.1",
@@ -21,15 +22,17 @@
"axios": "^0.26.0", "axios": "^0.26.0",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"cors": "^2.8.5", "cors": "^2.8.5",
"cross-fetch": "^4.0.0",
"dotenv": "^16.0.0", "dotenv": "^16.0.0",
"express": "^4.17.2", "express": "^4.17.2",
"fortawesome": "^0.0.1-security", "fortawesome": "^0.0.1-security",
"html2canvas-pro": "^1.5.3",
"joi": "^17.6.0", "joi": "^17.6.0",
"loglevel": "^1.8.0", "loglevel": "^1.8.0",
"loglevel-plugin-remote": "^0.6.8", "loglevel-plugin-remote": "^0.6.8",
"playwright": "^1.18.1", "playwright": "^1.18.1",
"playwright-extra": "^4.3.6",
"prismjs": "^1.28.0", "prismjs": "^1.28.0",
"puppeteer-extra-plugin-stealth": "^2.11.2",
"react": "^18.0.0", "react": "^18.0.0",
"react-dom": "^18.0.0", "react-dom": "^18.0.0",
"react-highlight": "^0.14.0", "react-highlight": "^0.14.0",

View File

@@ -38,7 +38,7 @@ export class BrowserPool {
/** /**
* Holds all the instances of remote browsers. * Holds all the instances of remote browsers.
*/ */
private pool : PoolDictionary = {}; private pool: PoolDictionary = {};
/** /**
* Adds a remote browser instance to the pool indexed by the id. * Adds a remote browser instance to the pool indexed by the id.
@@ -62,12 +62,12 @@ export class BrowserPool {
* @param id remote browser instance's id * @param id remote browser instance's id
* @returns true if the browser was removed successfully, false otherwise * @returns true if the browser was removed successfully, false otherwise
*/ */
public deleteRemoteBrowser = (id: string) : boolean => { public deleteRemoteBrowser = (id: string): boolean => {
if (!this.pool[id]) { if (!this.pool[id]) {
logger.log('warn', `Remote browser with id: ${id} does not exist in the pool`); logger.log('warn', `Remote browser with id: ${id} does not exist in the pool`);
return false; return false;
} }
delete(this.pool[id]); delete (this.pool[id]);
logger.log('debug', `Remote browser with id: ${id} deleted from the pool`); logger.log('debug', `Remote browser with id: ${id} deleted from the pool`);
return true; return true;
}; };
@@ -77,7 +77,7 @@ export class BrowserPool {
* @param id remote browser instance's id * @param id remote browser instance's id
* @returns remote browser instance or undefined if it does not exist in the pool * @returns remote browser instance or undefined if it does not exist in the pool
*/ */
public getRemoteBrowser = (id: string) : RemoteBrowser | undefined => { public getRemoteBrowser = (id: string): RemoteBrowser | undefined => {
logger.log('debug', `Remote browser with id: ${id} retrieved from the pool`); logger.log('debug', `Remote browser with id: ${id} retrieved from the pool`);
return this.pool[id]?.browser; return this.pool[id]?.browser;
}; };
@@ -88,7 +88,7 @@ export class BrowserPool {
* If there are multiple active browsers, it returns the first one. * If there are multiple active browsers, it returns the first one.
* @returns the first remote active browser instance's id from the pool * @returns the first remote active browser instance's id from the pool
*/ */
public getActiveBrowserId = () : string | null => { public getActiveBrowserId = (): string | null => {
for (const id of Object.keys(this.pool)) { for (const id of Object.keys(this.pool)) {
if (this.pool[id].active) { if (this.pool[id].active) {
return id; return id;

View File

@@ -5,12 +5,16 @@ import {
BrowserContext, BrowserContext,
} from 'playwright'; } from 'playwright';
import { Socket } from "socket.io"; import { Socket } from "socket.io";
import { fullLists, PlaywrightBlocker, Request } from '@cliqz/adblocker-playwright';
import fetch from 'cross-fetch';
import logger from '../../logger'; import logger from '../../logger';
import { InterpreterSettings, RemoteBrowserOptions } from "../../types"; import { InterpreterSettings, RemoteBrowserOptions } from "../../types";
import { WorkflowGenerator } from "../../workflow-management/classes/Generator"; import { WorkflowGenerator } from "../../workflow-management/classes/Generator";
import { WorkflowInterpreter } from "../../workflow-management/classes/Interpreter"; import { WorkflowInterpreter } from "../../workflow-management/classes/Interpreter";
/** /**
* This class represents a remote browser instance. * This class represents a remote browser instance.
* It is used to allow a variety of interaction with the Playwright's browser instance. * It is used to allow a variety of interaction with the Playwright's browser instance.
@@ -88,7 +92,10 @@ export class RemoteBrowser {
this.browser = <Browser>(await options.browser.launch(options.launchOptions)); this.browser = <Browser>(await options.browser.launch(options.launchOptions));
const context = await this.browser.newContext(); const context = await this.browser.newContext();
this.currentPage = await context.newPage(); this.currentPage = await context.newPage();
const blocker = await PlaywrightBlocker.fromPrebuiltAdsAndTracking(fetch);
await blocker.enableBlockingInPage(this.currentPage);
this.client = await this.currentPage.context().newCDPSession(this.currentPage); this.client = await this.currentPage.context().newCDPSession(this.currentPage);
await blocker.disableBlockingInPage(this.currentPage);
}; };
/** /**

View File

@@ -11,10 +11,12 @@ import {
stopRunningInterpretation, stopRunningInterpretation,
getRemoteBrowserCurrentUrl, getRemoteBrowserCurrentTabs, getRemoteBrowserCurrentUrl, getRemoteBrowserCurrentTabs,
} from '../browser-management/controller' } from '../browser-management/controller'
import { chromium } from "playwright"; import { chromium } from 'playwright-extra';
import stealthPlugin from 'puppeteer-extra-plugin-stealth';
import logger from "../logger"; import logger from "../logger";
export const router = Router(); export const router = Router();
chromium.use(stealthPlugin());
/** /**
* Logs information about remote browser recording session. * Logs information about remote browser recording session.

View File

@@ -89,4 +89,4 @@ export const getBestSelectorForAction = (action: Action) => {
break; break;
} }
return null; return null;
} }

9
src/App.test.tsx Normal file
View File

@@ -0,0 +1,9 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});