How do I get "dragAndDrop" to work with Selenium using JavaScript? - javascript

I am creating a Selenium test for a web page that I am working on and I am getting stuck trying to use the dragAndDrop action. I need to use this action to re-order a wait list that I have. I am new when it comes to Selenium and i'm not sure if I am using correct syntax for the dragAndDrop action. I would appreciate it if someone could help lead me in the right direction. Below is my current code minus some other test I wrote.
const webdriver = require('selenium-webdriver');
const keys = webdriver.Key;
const chromedriver = require('chromedriver');
const chrome = require('selenium-webdriver/chrome');
const rp = require('request-promise');
const chai = require('chai');
const assert = chai.assert;
const expect = chai.expect;
const should = chai.should();
const WebElement = require('selenium-webdriver');
const actions = require('selenium-webdriver/lib/input');
driver = new webdriver.Builder().forBrowser('chrome').build();
describe('This is for testing the Rewards Portal using Selenium', function() {
this.timeout(60000);
it('Should reorder the customers', async function () {
let drag = driver.findElement(webdriver.By.xpath('//*[#id="LiveScheduleList"]/ul/li[1]/div[2]'));
let drop = driver.findElement(webdriver.By.xpath('//*[#id="LiveScheduleList"]/ul/li[2]/div[2]'));
await driver.sleep(2500);
await driver.executeScript("document.querySelector('#ChangeOrderBtn').click();");
await driver.sleep(2500);
await actions.dragAndDrop(drag, drop);
});
};
When I run it I get this back:
TypeError: actions.dragAndDrop is not a function

You are using actions incorrectly.
Your code should look like...
await driver.
actions().
dragAndDrop(drag, drop);
PD: BTW, using sleep to synchronize your code is not a best practice...

Related

.sendSignedTransaction() Not sending Tx

Bit of context; this was working fine on Goerli just a few days a go but the script now works intermittently. At the moment im thinking its down to one of the following:
Node issue - currently using infura and have tried changing it across other public RPCS but didn't work any better
Web3 issue - not sure if something is now outdated
Nonce issue with wallets, not sure if there is something obvious in the code here that is causing my Txs to get stuck and as such never return a receipt
For some reason this was all working fine last night after having not worked all day. Bit stuck as to what i could be doing wrong tbh. The logic is that based on a mempool tx, the sendTx function is invoked with the 'targetAddress' param which contains all the necessary objects to replicate the tx which i am tracking.
Tx.js:
const Web3 = require('web3');
const Tx = require('ethereumjs-tx');
process.removeAllListeners('warning');
require('dotenv').config();
const INFURA_URL_TESTNET = process.env.INFURA_URL_TESTNET;
const web3 = new Web3(INFURA_URL_TESTNET);
const BN = web3.utils.BN;
// Tx details:
const sendTx = async (targetAddress) => {
const address = targetAddress.address;
const ethAmmount = targetAddress.value;
const data = targetAddress.input;
const gasLimit = targetAddress.gas;
//const gasPrice = targetAddress.gasPrice - web3.utils.toWei('1', 'gwei');
const maxFeePerGas = targetAddress.maxFeePerGas //- 1000000;
const maxPriorityFeePerGas = targetAddress.maxPriorityFeePerGas //- 1000000;
const privKey = targetAddress.privKey;
const from = targetAddress.from;
const _txCount = await web3.eth.getTransactionCount(from);
const createTransaction = await web3.eth.accounts.signTransaction(
{ to: address,
from: from,
data: data,
gas: gasLimit,
value: ethAmmount,
nonce: _txCount,
maxFeePerGas: maxFeePerGas,
maxPriorityFeePerGas: maxPriorityFeePerGas,
},
privKey,
);
// Send Tx and Wait for Receipt
const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction);
//const transaction = await web3.eth.getTransaction(createReceipt.transactionHash);
console.log(`Tx successful with hash: ${createReceipt.transactionHash}`);
};
module.exports = {sendTx};
The code stops at the await .sendSignedTx and doesn't return a receipt. As i said, this does work exactly as expected sometimes and i can figure out why sometimes it works and sometimes it doesn't?
Thanks everyone!
Since you are using web3js, you have to handle the event promise chain when calling sendSignedTransaction and log all the payloads. That will tell you the reason for it not being broadcast. Could be a network error, gas issue, maybe nonce .e.t.c.
See https://web3js.readthedocs.io/en/v1.2.11/callbacks-promises-events.html#callbacks-promises-events

events.Swap is not triggered in web3 for a Uniswap Pool

Visual Studio Code 1.66.2
ganache v7.1.0 (#ganache/cli: 0.2.0, #ganache
I am new to Solidity and this is my first example I am trying out.
I am trying to get noticed when there is a swap event in the Uniswap Pool "ETH-APE" using:
uPair.events.Swap
The code seems to start where: Waiting for swaps...
I can see on Uniswap itself that there is regular swaps but the swap event seems to not trigger where the console.log should show: someone swapped now!
I have started this blockchain successfully with the command like this:
Notice: I have a real apikey from alchemy and a real mnemonic from ganache-cli
ganache-cli -f wss://eth-mainnet.alchemyapi.io/v2/myAPIkey --mnemonic "word1 word2 word3 etc" -p 7545
I have just followed some examples and are not sure exactly what I am doing:
As I am a beginner I must also ask about ganache. As I have understand this is a "Fake and local Sandboxed" blockchain just existing on my computer?
I think I understand that I start ganache-cli on my computer but are not sure if the uPair.events.Swap listen to my local blockchain which is not the REAL blockchain and this is because the swap event is not triggered. If that is the case then that is what I wonder what I am missing?
(I am not even sure I need ganache to listen to this swap event?)
I am not sure what the alchemyapi.io with myAPIkey is doing in the command to start the local ganache-cli where in the same command I use the mnemonic which has been generated from ganache?
// -- HANDLE INITIAL SETUP -- //
require("dotenv").config();
const Web3 = require('web3')
const IERC20 = require('#openzeppelin/contracts/build/contracts/ERC20.json')
const IUniswapV2Pair = require("#uniswap/v2-core/build/IUniswapV2Pair.json")
const IUniswapV2Factory = require("#uniswap/v2-core/build/IUniswapV2Factory.json")
const { ChainId, Token } = require("#uniswap/sdk")
let web3 = new Web3('ws://127.0.0.1:7545')
const main = async () => {
const _eth_address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
const _apecoin_address = "0x4d224452801aced8b2f0aebe155379bb5d594381";
const _uniswap_factory_address = "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f";
const uFactory = new web3.eth.Contract(IUniswapV2Factory.abi, _uniswap_factory_address) // UNISWAP FACTORY CONTRACT
const { token0Contract, token1Contract, token0, token1 } = await getTokenAndContract(_eth_address, _apecoin_address)
let uPair = await getPairContract(uFactory, token0.address, token1.address)
console.log("Waiting for swaps...");
uPair.events.Swap({}, async () => {
console.log("someone swapped now!");
})
}
async function getPairAddress(_V2Factory, _token0, _token1) {
const pairAddress = await _V2Factory.methods.getPair(_token0, _token1).call()
return pairAddress
}
async function getPairContract(_V2Factory, _token0, _token1) {
const pairAddress = await getPairAddress(_V2Factory, _token0, _token1)
const pairContract = new web3.eth.Contract(IUniswapV2Pair.abi, pairAddress)
return pairContract
}
async function getTokenAndContract(_token0Address, _token1Address) {
const token0Contract = new web3.eth.Contract(IERC20.abi, _token0Address)
const token1Contract = new web3.eth.Contract(IERC20.abi, _token1Address)
const token0 = new Token(
ChainId.MAINNET,
_token0Address,
18,
await token0Contract.methods.symbol().call(),
await token0Contract.methods.name().call()
)
const token1 = new Token(
ChainId.MAINNET,
_token1Address,
18,
await token1Contract.methods.symbol().call(),
await token1Contract.methods.name().call()
)
return { token0Contract, token1Contract, token0, token1 }
}
main()

.balanceOf is not a function - Interact with existing Contract on Blockchain

I want to automate my staking on The Sandbox. For that I need in the first step to interact with the mSand-Matic Pool Contract. It is this one: https://polygonscan.com/address/0x4ab071c42c28c4858c4bac171f06b13586b20f30#code
I have written a little program in a GitHub repository to show what I have done: https://github.com/ChristianErdtmann/mSandMaticStakingAutomation
Or here is the code example from the contract-interact.js
Web3 = require('web3')
const fs = require('fs');
const web3 = new Web3("https://polygon-rpc.com")
const contractAddress = "0x4AB071C42C28c4858C4BAc171F06b13586b20F30"
const contractJson = fs.readFileSync('./abi.json')
const abi = JSON.parse(contractJson)
const mSandMaticContract = new web3.eth.Contract(abi, contractAddress)
mSandMaticContract.balanceOf('0x7e5475290Df8E66234A541483453B5503551C780')
The ABI I have taken from the contract link on the top. But it seems there is a problem.
I tried for testing to read something from the contract. For that I used the function balanceOf(address), how you can see in the code.
But I always get this error:
TypeError: mSandMaticContract.balanceOf is not a function
I found the solution
web3 needs .methots to get acces to the balanceOf() function
if we want only to read so we need to add .call()
we need to add await before the function is called this needs to be in a asynchonus function
So the final working code is:
Web3 = require('web3')
const fs = require('fs');
const web3 = new Web3("https://polygon-rpc.com")
const contractAddress = "0x4AB071C42C28c4858C4BAc171F06b13586b20F30"
const contractJson = fs.readFileSync('./abi.json')
const abi = JSON.parse(contractJson)
const mSandMaticContract = new web3.eth.Contract(abi, contractAddress)
asyncCall()
async function asyncCall() {
console.log(await mSandMaticContract.methods.balanceOf('0x7e5475290Df8E66234A541483453B5503551C780').call())
}
If you dont want only to read you need addtional to sign the transaction with:
The solution is, to sign the transaction before sending we can doing this with any method by this code:
encoded = mSandMaticContract.methods.getReward().encodeABI()
var block = await web3.eth.getBlock("latest");
var gasLimit = Math.round(block.gasLimit / block.transactions.length);
var tx = {
gas: gasLimit,
to: publicKey,
data: encoded
}
web3.eth.accounts.signTransaction(tx, privateKey).then(signed => {
web3.eth.sendSignedTransaction(signed.rawTransaction).on('receipt', console.log)
})

Node.js PDFjs fetching specific page using pdfjs-dist

I'm trying to fetch the contents of page 4 of a PDF file using 'pdfjs-dist'.
I've tried to replace the 'pdfjs-dist' module with 'const pdfjs = require("pdfjs/es5/build/pdf")' but with no success.
What could be problem?
Thanks in advance!
const pdfjs = require('pdfjs-dist'); // Fetch PDF
async function getContent(src) {
const doc = await pdfjs.getDocument(src).promise // note the use of the property promise
const page = await doc.getPage(4)
return await page.getTextContent()
}
console.log(getContent('pdfs/Quantum.pdf'))
It's too late to reply to this questions but let me add the solution that worked for me for those who will wish to implement the some issue.
This is the code that will work fine
// Install the latest version of pdf.js via npm i pdfjs-dist
const pdfjsLib = require("pdfjs-dist/legacy/build/pdf.js");
let pdf_path = "{RELATIVE_PATH_TO_YOUR_FILE}/sample.pdf";
async function getContent(src: any){
const doc = await pdfjsLib.getDocument(src).promise;
const page = await doc.getPage(1);
const strings: any = await page.getTextContent();
let ITEMS_STRINGS = strings.items.map((item: any) => item.str);
let PDF_STRINGS: string = ITEMS_STRINGS.join(" ");
return PDF_STRINGS;
}
console.log(await getContent(`${pdf_path}`));
This will work fine

Unable to retrieve contents of Chrome Console using Selenium Webdriver in Node.js

I am trying to read the Chrome console using Selenium Webdriver in node.js, but so far it is unsuccessful. There are no errors. But all it returns is an empty array [].
The following is a snippet of the HTML and JavaScript function. When run manually in Chrome, these write to the console just fine.
<button name="button1" type="button" onclick="test_console()">Test</button>
function test_console() {
console.log("Hello World");
}
The following is the code I am using in node.js to try to get the output to Chrome.
const webdriver = require('selenium-webdriver');
const chromeDriver = require('selenium-webdriver/chrome');
const logging = require('selenium-webdriver').logging;
const path = require('chromeDriver').path;
const service = new chromeDriver.ServiceBuilder(path).build();
chromeDriver.setDefaultService(service);
const {By, Key} = webdriver;
webdriver.promise.USE_PROMISE_MANAGER = false;
const CHROME_BIN_PATH = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome';
const prefs = new logging.Preferences();
prefs.setLevel(logging.Type.BROWSER, logging.Level.ALL);
const options = new chromeDriver.Options();
options.setChromeBinaryPath(CHROME_BIN_PATH);
options.addArguments(
'headless',
'disable-gpu',
'verbose',
'disable-impl-side-painting',
);
const main = async () => {
try {
const driver = await new webdriver.Builder()
.withCapabilities(webdriver.Capabilities.chrome())
.setLoggingPrefs(prefs)
.forBrowser('chrome')
.setChromeOptions(options)
.build();
await driver.get('http://example.com/example.html');
//clicking this button manually in Chrome writes to the console
await driver.findElement(By.name('button1')).click();
await driver.manage().logs().get(logging.Type.BROWSER)
.then(function(entries) {
console.log(entries);
});
await driver.close();
await driver.quit();
} catch (error) {
await driver.close();
await driver.quit();
console.log(error);
}
};
main();
I'm sure the issue is simple, probably a configuration problem. I just cant figure out what the problem might be. I even resorted to reading the webdriver source code in Git to see if I could see anything, but to no avail.
As far as I can tell, getting the contents of the console from Chrome using webdriver is a no go.
I ended up solving the issue in this manner:
//append a div to the body of the page
await driver.executeScript("var div = document.createElement('div'); div.id = 'console_log'; document.body.appendChild(div);");
//override console.log to write the log message to the new div
await driver.executeScript("console.log = function(message){document.getElementById('console_log').innerHTML += message}");
//get the contents of the new div
const console_log = await driver.findElement(By.id('console_log'));
console.log(await console_log.getAttribute('innerHTML'));

Categories