Configure WebDriverIO with BrowserMobProxy - javascript

Does anyone have a proper example on how to configure BrowserMobProxy with WebDriverIO? This is so I can capture network traffic. I previously had it working with WebDriverJS, which is essentially a deprecated version of WebDriverIO.

You can use the below code to do that. Make sure your browsermob proxy and selenium server is running. Then copy paste below code in a test.js file and put it in webdriverio installed folder. From cmd go to that folder and run node test.js . stuff.har should be generated where test.js is located.
var Proxy = require('browsermob-proxy').Proxy
, webdriverio = require("./node_modules/webdriverio/")
, fs = require('fs')
, proxy = new Proxy()
;
proxy.cbHAR('search.yahoo.com', doSeleniumStuff, function(err, data) {
if (err) {
console.error('ERR: ' + err);
} else {
fs.writeFileSync('stuff.har', data, 'utf8');
}
});
function doSeleniumStuff(proxy, cb) {
var browser = webdriverio.remote({
host: 'localhost'
, port: 4444
, desiredCapabilities: { browserName: 'firefox', seleniumProtocol: 'WebDriver', proxy: { httpProxy: proxy } }
});
browser
.init()
.url("http://search.yahoo.com")
.setValue("#yschsp", "javascript")
.submitForm("#sf")
.end().then(cb);
}

If you just want to capture the network traffic, then there is one more way to do it.
Webdriverio allows you to use Chrome Dev Tools Protocol.
Please read webdriverio blog
This is one of the examples on how to use chrome dev tools along with webdriverio, do let me know in case you need more help.
const { remote } = require('webdriverio')
let browser;
(async () => {
browser = await remote({
automationProtocol: 'devtools',
capabilities: {
browserName: 'chrome'
}
})
await browser.url('https://webdriver.io')
await browser.call(async () => {
const puppeteerBrowser = browser.getPuppeteer()
const page = (await puppeteerBrowser.pages())[0]
await page.setRequestInterception(true)
page.on('request', interceptedRequest => {
if (interceptedRequest.url().endsWith('webdriverio.png')) {
return interceptedRequest.continue({
url: 'https://user-images.githubusercontent.com/10379601/29446482-04f7036a-841f-11e7-9872-91d1fc2ea683.png'
})
}
interceptedRequest.continue()
})
})
// continue with WebDriver commands
await browser.refresh()
await browser.pause(2000)
await browser.deleteSession()
})().catch(async (e) => {
console.error(e)
await browser.deleteSession()
})

Since I had no luck solving this problem using browsermob proxy (AFAIK it wasn't updated in a while)
I created a small npm module to capture selenium tests as HAR files - https://www.npmjs.com/package/har-recorder
I took #Raulster24 suggestion and implemented it using the Chrome Dev Tools Protocol - https://github.com/loadmill/har-recorder/blob/master/index.js

Related

How to connect any server using ssh in Cypress.io to run a command?

I know that this probably is not the best way to do this. I read the question with the same title here, but it not solve my problem.
The question is: I have a server that only will achieve a result that I wanna if I run a command line in the server. So I wanna write a test to check the state of one page before and after I run that command. How I do that?
I tried to use the simple-ssh package, but I keep getting this error while trying to read the ssh key file:
fs.readFileSync is not a function
Actually my code looks like this:
import * as fs from 'fs';
let sshConfig = Cypress.config('ssh')
sshConfig.key = fs.readFileSync('path/to/key/file')
let SSH = require('simple-ssh');
Cypress.Commands.add('teste', () => {
let ssh = new SSH(sshConfig)
ssh.exec('echo', {
args: ['$PATH'],
out: function(stdout) {
console.log(stdout);
}
}).start();
})
Other possibility's are welcome.
As Fody mentioned, there are node.js functions present inside simple-ssh so a task is needed.
This is the basic configuration.
It's a direct translation of what you have, but you would want to return something from the task. As it is, the console.log() goes to the terminal console not the browser console.
cypress.config.js
const { defineConfig } = require('cypress')
const fs = require('fs')
const SSH = require('simple-ssh');
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('task', {
ssh() {
const sshConfig = config.ssh
sshConfig.key = fs.readFileSync('path/to/key/file')
const ssh = new SSH(sshConfig)
ssh.exec('echo', {
args: ['$PATH'],
out: function(stdout) {
console.log(stdout);
}
}).start();
return null
},
})
}
}
})
test
Cypress.Commands.add('ssh', () => {
cy.task('ssh')
})
cy.ssh()
Try it with cy.readFile().
const SSH = require('simple-ssh');
Cypress.Commands.add('testSSH', () => {
cy.readFile('path/to/key/file').then(key
const sshConfig = Cypress.config('ssh')
sshConfig.key = key
const ssh = new SSH(sshConfig)
ssh.exec('echo', {
args: ['$PATH'],
out: function(stdout) {
console.log(stdout);
}
}).start()
})
})
The problem is fs is a node.js library, and it cannot be used in the browser.
But you may find the same thing applies to simple-ssh, If so, you will have to shift the code into a task where you can use any node.js functions.

How to use async / await in Chrome or Edge mobile browser?

I've completed my first JavaScript course and am now following a course on React. I've created a simple backend using Express and MongoDB.
I've created a frontend using npx create-react-app, added axios to communicate with the backend and am using antd for the UI. So far so good! The following code works on my laptop running Windows 10 and Edge 94 to insert a new Year into MongoDB using a simple input:
Client uses:
const onFinish = async (values) => {
await api.createYear(values).then((res) => {
console.log("onFinish", values);
console.log(res);
});
};
API uses:
import axios from 'axios'
const api = axios.create({
baseURL: 'http://localhost:3000/api/v1',
})
export const createYear = values => api.post(`/year`, values)
Server (controller) uses:
const Year = require('../models/year-model')
createYear = (req, res) => {
const body = req.body
if (!body) {
return res.status(400).json({
success: false,
error: 'You must provide a year!',
})
}
const year = new Year(body)
if (!year) {
return res.status(400).json({ success: false, error: err })
}
year
.save()
.then(() => {
return res.status(201).json({
success: true,
id: year._id,
message: 'Year created!',
})
})
.catch(error => {
return res.status(400).json({
error,
message: 'Year not created!',
})
})
}
Server (model) uses:
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const yearSchema = new Schema(
{
year: { type: Number, required: true }
},
{ timestamps: false },
)
module.exports = mongoose.model('Year', yearSchema)
However, the same code does not work on my Samsung Galaxy S21 using Edge 93 and Chrome 94. Based on what I found so far, this could be caused by this browser not supporting async/await (ES2017 feature). This could probably be resolved by Babel?
I'm sorry that this part is pretty vague: the information I found is a kind of overwhelming considering my limited experience and all variables involved (React version, Babel version, Babel plugins, Webpack etc). I would gladly provide more information if you could point me in the right direction.
Could anyone perhaps tell me if and how I should change Babel or Webpack to make async/await work in mobile browsers?
If the problem is that async/await doesn't work on those browsers, then I think you can change your .babelrc file to target older browsers.
However, to address #ammar's points, maybe double check that:
you can see web pages served by your laptop on your phone
your phone browser doesn't work with async/await
I would create a simple html page that looks like this to make sure that this is the problem.
<html>
<head></head>
<body>
<div>TEST PAGE<div>
<div id='test'></div>
<script>
function sleep(t) {
return new Promise(function(resolve) {
setTimeout(resolve, t);
});
}
(async function() {
for (let x = 0; x < 1000; x++) {
document.getElementById('test').innerHTML = x;
await sleep(1000);
}
})();
</script>
<body>
</html>
I would attack it like this:
save the above as test.html
open the file directly with your laptop browser and see the count-up
figure out how to serve the same file as static content with the webpack dev server, and open it in the laptop browser
open the same file on your mobile device to prove that you can see the page at all, and that async/await is not working

error sending request for url (https://deno.land/std/encoding/csv.ts) (os error 10013)

Unable to import the stdlib files from deno.land to local cache on running mod.ts.
error: error sending request for url (https://deno.land/std/encoding/csv.ts): error trying to connect: tcp connect error: An attempt was made to access
a socket in a way forbidden by its access permissions. (os error 10013)
Imported from "file:///C:/Current_Tasks/Deno/Kepler/mod.ts:3"
Is there anything additional that needs to be enabled to import these files?
import { join } from "https://deno.land/std/path/mod.ts";
import { BufReader } from "https://deno.land/std/io/bufio.ts";
import { parse } from "https://deno.land/std/encoding/csv.ts";
async function loadPlanetsData() {
const path = join(".", "test.csv");
const file = await Deno.open(path);
const bufReader = new BufReader(file);
const result = await parse(bufReader, {
header: true,
comment: "#",
});
Deno.close(file.rid);
console.log(result);
}
await loadPlanetsData();
Update: Used
deno run --allow-read mod.ts
import { join } from "https://deno.land/std/path/mod.ts";
import { BufReader } from "https://deno.land/std/io/bufio.ts";
import { parse } from "https://deno.land/std/encoding/csv.ts";
async function loadPlanetsData() {
const path = join(".", "test.csv");
const file = await Deno.open(path);
const bufReader = new BufReader(file);
const result = await parse(bufReader, {
header: true,
comment: "#",
});
Deno.close(file.rid);
console.log(result);
}
await loadPlanetsData();
While running this file you need to give read access to the Deno.
Deno is secure by default. Therefore, unless you specifically enable it, a deno module has no file, network, or environment access for example. Access to security sensitive areas or functions requires the use of permissions to be granted to a deno process on the command line.
For the following example, mod.ts has been granted read-only access to the file system. It cannot write to it, or perform any other security sensitive functions.
deno run --allow-read mod.ts

require('fs-extra') not loading: throwing error "Cant find module fs-extra"

Trying to use some installed npm packages like fs-extra into below js files given by Truffle.But it says "can't find module "fs-extra".
1) Tried importing local js files using require() method but that fails too.
2) Tried running separate js files using node and it works just fine.
3) Issue comes when I try to use require("fs-extra") inside a function declared in APP object.
App = {
web3Provider: null,
contracts: {},
init: async function () {
return await App.initWeb3();
},
initWeb3: async function () {
// Modern dapp browsers...
if (window.ethereum) {
App.web3Provider = window.ethereum;
try {
// Request account access
await window.ethereum.enable();
} catch (error) {
// User denied account access...
console.error("User denied account access")
}
}
// Legacy dapp browsers...
else if (window.web3) {
App.web3Provider = window.web3.currentProvider;
}
// If no injected web3 instance is detected, fall back to Ganache
else {
App.web3Provider = new Web3.providers.HttpProvider('http://0.0.0.0:9283');
}
web3 = new Web3(App.web3Provider);
return App.initContract();
},
initContract: function () {
$.getJSON('UserCreation.json', function (data) { //<VK>Satish to add his contract file here
// Get the necessary contract artifact file and instantiate it with truffle-contract
var CMArtifact = data;
App.contracts.UserCreation = TruffleContract(CMArtifact);
App.contracts.UserCreation.setProvider(App.web3Provider);
});
return App.bindEvents();
},
createUser: function (event) {
event.preventDefault();
var username = $("#sign-up-username").val();
var title = $("#sign-up-title").val();
var intro = $("#sign-up-intro").val();
const utility=require('fs-extra'); // Failing to find module
}
}
$(function () {
console.log("initiaing farmer")
$(window).load(function () {
App.init();
});
});
Expected: Should be able to call methods from fs-extra package
Actual : can't find module "fs-extra"
npm ls fs-extra to check if you've installed it correctly. Then try npm install fs-extra.
require('fs-extra') will only work in server side javascript (nodejs) .
If your code runs on a browser require will not work

How to connect VPN using nodejs in ubuntu

I have the code in my nodejs file which gives me the following information
host:"147.0.40.145"
method:"aes-256-cfb"
password:"9c359ad1ebeec200"
port:38473
I need to use above information and want to connect VPN through it. I have used below code to extract the above information.
const connectServer = (serverId) => {
const token = store('access_token')
httpOptions.Authorization = token.token_type+' '+token.access_token
return new Promise((resolve, reject) => {
const response = await axios.post(`${baseUrl}/servers/${serverId}/connect`, {'serverId':serverId},{headers: httpOptions})
console.log(response.data)
resolve(response.data)
})
}
So I need to know whether it is possible using nodejs to connect or create VPN?
Thank you in advance!!!
Install this npm
npm i node-openvpn --save
const openvpnmanager = require('node-openvpn');
const opts = {
host: '147.0.40.145',
port: 38473,
timeout: 1500, //timeout for connection - optional, will default to 1500ms if undefined
logpath: 'log.txt' //optional write openvpn console output to file, can be relative path or absolute
};
const auth = {
user: '{{add user name}}',
pass: '9c359ad1ebeec200',
};
const openvpn = openvpnmanager.connect(opts)
openvpn.on('connected', () => {
console.log("Connected to VPN successfully...");
});
For more info , please read this link
Another option
Link

Categories