Proxies in selenium node js - node.js

I have been trying for past few days to build a selenium browser with proxies in node.js. I have researched the topic and none of the provided solutions worked for me because they were deprecated or outdated. I have tried different plugins and methods. Could someone answered me with the correct code example or linked me to a solution.

Here you go
const { Builder } = require('selenium-webdriver')
const chrome = require('selenium-webdriver/chrome')
const PROXY = "190.60.104.218:3128"
const option = new chrome.Options().addArguments(`--proxy-server=http://${PROXY}`)
const driver = new Builder().forBrowser('chrome').setChromeOptions(option).build()
driver.get('http://httpbin.org/ip')
.then(() => console.log('DONE'))
Proxy is not anonymous so the original IP is also appearing

Related

how to modify https traffic in google chrome using nodejs?

Like a question, of course I didn't do it because of illegal behavior.
For example, I have a link: https://example.com/inj.php
The result I get for example is:
<h1>Hello world</h1>
How can I fix it using only nodejs code?
<h1>Hello world</h1>
<h2>inject</h2>
I think you need to create a proxy and that device needs to install and configure your self-signed CA.
I wrote a library for personal use, it works pretty well
npm i pms-proxy
As your question above, it can be written as
const https = await PPCa.generateCACertificate();
const spki = PPCa.generateSPKIFingerprint((<PPCaFileOptions>https).cert);
const userData = path.join('C:/test-chrome');
const server = new PPServerProxy({https});
const pass = new PPPassThroughHttpHandler();
pass.injectBuffer((req, buffer) => {
return {
data: buffer.toString() + "<h2>inject</h2>"
};
})
server.addRule().url('https://example.com/inj.php').then(pass);
await server.listen(1234);
// node module
child_process.exec(
`start chrome --proxy-server="http://127.0.0.1:1234" --ignore-certificate-errors-spki-list=\"${spki}\" --user-data-dir=\"${userData}\"`
);
If you don't want to use SPKI Fingerprint you can create a self-signed CA, follow the README in the package:
https://www.npmjs.com/package/pms-proxy

Add options to selenium chrome browser using nodejs

I am using selenium with Node.js in this way
import {Builder, Browser, By, Key, until} from "selenium-webdriver";
let driver = await new Builder().forBrowser(Browser.CHROME).build();
I want to add chrome options in this way
const chrome = require('selenium-webdriver/chrome')
const options = new chrome.Options()
options.addArguments('--disable-dev-shm-usage')
options.addArguments('--no-sandbox')
options.addArguments('--headless')
let driver = await new Builder().forBrowser(Browser.CHROME).setChromeOptions(options).build();
But I can only use imports in my project, I can't use require. I get the following error because of this line
const chrome = require('selenium-webdriver/chrome')
require is not defined in ES module scope, you can use import instead
How can I import chrome instead of require it to add the option? I am importing a lot of module in my code, It will be really difficult to change them all to requires
You can refer to the file as "selenium-webdriver/chrome.js". I.e.:
import {Options} from "selenium-webdriver/chrome.js";
const options = new Options();
// use options as you always would...

How to use Bolt events with the newer Slack API manifests?

I'm building a Slack App using Bolt and I've got the basics working using Socket Mode. The docs say that socket mode apps are not allowed in the public directory, which I do want my App in when it's ready. I've now turned off socket mode and got ngrok working as described here. Slack was able to validate the url anyway.
But what's not working is a slash command. The manifest editor says the url is required for a slash command, but how does that line up with bolt? Are there better docs for non-socket-mode somewhere? It seems like every example of using bolt says "let's use socket mode, it's easy".
Manifest portion:
slash_commands:
- command: /sb
url: https://[my url].ngrok.io/slack/command
Sample code:
const { App } = require('#slack/bolt');
const express = require('express');
const app = express();
const boltApp = new App({
signingSecret: config.slackApp.signingSecret,
token: config.slackApp.token,
endpoints = '/'
});
app.use('/slack/events', boltApp.receiver.router);
Bolt
Slack App Manifests
I got this working with a combination of the following:
setting every url in the manifest (slash_commands, event_subscriptions, interactivity) to https://foo.ngrok.io/slack/
attaching Bolt to an existing Express App, attempting to follow this PR to use app and/or router config prop on ExpressReceiver, but strangely what worked was putting the express app into the router
setting up Bolt like below
Example Code:
const expressApp = express();
...
const boltReceiver = new ExpressReceiver({
router: expressApp,
signingSecret: SLACK_SIGNING_SECRET,
endpoints: '/slack'
});
const boltApp = new App({
token: SLACK_BOT_TOKEN,
receiver: boltReceiver,
appToken: SLACK_APP_TOKEN,
socketMode: false,
});

Connect Testcafe to AWS Devicefarm

We recently decided to include E2E to our front-end pipeline and we are using testCafe for that and since we use AWS as our SaaS we're being asked to use Devicefarm for remote testing and I'm facing the problem to connect them. I'm based on the selenium implementations and the testCafe documentation but it seems not to be able to establish connection between them, anyone has any idea why?
My code:
const AWS = require('aws-sdk');
const createTestCafe = require('testcafe');
const PROJECT_ARN = "arn:aws:devicefarm:us-west-2:XXXXXXXX:testgrid-project:XXXXXX-XXXX-XXXX-XXXX-XXXXXXXX";
const devicefarm = new AWS.DeviceFarm({ region: "us-west-2", credentials: AWS.config.credentials });
(async () => {
const testGridUrlResult = await devicefarm.createTestGridUrl({
projectArn: PROJECT_ARN,
expiresInSeconds: 6000
}).promise();
const url = new URL(testGridUrlResult.url || '');
const testCafe = await createTestCafe(url.host, 443);
const runner = testCafe.createRunner();
const remoteConnection = await testCafe.createBrowserConnection();
remoteConnection.once('ready', async () => {
await runner
.src(['./load-mfc.ts'])
.browsers('devicefarm:firefox')
.run();
await testCafe.close();
});
})().catch((e) => console.error(e));
According to the AWS Device Farm documentation about the CreateTestGridUrl method:
Creates a signed, short-term URL that can be passed to a Selenium RemoteWebDriver constructor.
This URL can't be passed to the hostname property of the createTestCafe method because TestCafe doesn't implement the WebDriver protocol. TestCafe works differently then Selenium. Once you created a remote browser connection using TestCafe, you should navigate your remote browser to the browserConnection.url URL to connect to a TestCafe server instance and start test execution in this browser.
As the AWS Device Farm service uses the WebDriver protocol to operate remote browsers, you would need to write a custom Browser Provider Plugin for TestCafe. It may be helpful to read more in the TestCafe documentation about this topic and see how a similar thing is implemented in the BrowserStack provider.

How to download a CSV file with selenium while bypassing the file dialog

I have been trying to access a url with a CSV file to download it in a specific directory, using the Selenium Webdriver for Firefox(geckodriver), in a NodeJS enviroment on Linux-Mint.
This is my code:
const {Builder} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');
const path = require('path');
const options = new firefox.Options();
options.setPreference('browser.download.dir', path.resolve(__dirname));
options.setPreference('browser.download.folderList', 2);
options.setPreference('browser.helperApps.neverAsk.saveToDisk', 'application/x-csv');
function example(){
let driver = new Builder().forBrowser('firefox').setFirefoxOptions(options).build();
driver.get('http://insight.dev.schoolwires.com/HelpAssets/C2Assets/C2Files/C2ImportCalEventSample.csv');
}
example();
As you can see, I am correctly setting the browser option to browser.helperApps.neverAsk.saveToDisk, so as to be able to bypass the dialog. However, I am still getting the dialog no matter what I do. I haven't tried this code on Windows, but for my purposes it needs to work on Linux.
Am I missing something? Some preference that needs to be added or changed? Or does this not work on my current enviroment?
Thank you in advance for any help provided.
If you are just downloading a file from link why do you need selenium?
A much simple approach will be just to get the file by http and save to file.
const http = require('http');
const fs = require('fs');
const file = fs.createWriteStream("C2ImportCalEventSample.csv");
const request = http.get("http://insight.dev.schoolwires.com/HelpAssets/C2Assets/C2Files/C2ImportCalEventSample.csv", function(response) {
response.pipe(file);
});
If you have to use selenium let me know in the comments and i will try to find a solution for your problem using selenium.

Resources