Discord.js, JSDOM Invalid URL - discord.js

So I'm trying to get the HTML of a website. I use 'JSDOM' to "Load" the website due to a majority of the site being created using scripts. My code is as follows:
(async () => {
try {
const dom = new JSDOM(``, {
url: "https://www.google.com/",
referrer: "",
contentType: "text/html",
includeNodeLocations: true,
storageQuota: 10000000,
runScripts: "dangerously",
resources: "usable",
pretendToBeVisual: true
});
} catch(error) {
console.log(error)
}
})();
When I run the command I get the error
TypeError: Invalid URL:
at new URLImpl (C:\Users\jonco\Desktop\Nakada Manami\node_modules\whatwg-url\lib\URL-impl.js:21:13)
at Object.setup (C:\Users\jonco\Desktop\Nakada Manami\node_modules\whatwg-url\lib\URL.js:73:14)
at new URL (C:\Users\jonco\Desktop\Nakada Manami\node_modules\whatwg-url\lib\URL.js:105:22)
at transformOptions (C:\Users\jonco\Desktop\Nakada Manami\node_modules\jsdom\lib\api.js:239:43)
at new JSDOM (C:\Users\jonco\Desktop\Nakada Manami\node_modules\jsdom\lib\api.js:34:15)
at C:\Users\jonco\Desktop\Nakada Manami\index.js:109:16
at processTicksAndRejections (internal/process/task_queues.js:97:5)
What am I doing wrong? I've spend the last 3 hours trying to figure this out.

The referer has to be undefined or a valid URL.
As we see that in the source.

Related

Unhandled Rejection (TypeError): fs.createReadStream is not a function. Error at the time of image uploading to ipfs( pinata)

I was trying to upload image to pinata ipfs cloud from my frontend app of react js. But it shows me error:Unhandled Rejection (TypeError): fs.createReadStream is not a function. .
Here is my code snippet:
require('dotenv').config();
const fs = require('fs');
const axios = require('axios');
const FormData = require('form-data');
const key = process.env.REACT_APP_PINATA_KEY;
const secret = process.env.REACT_APP_PINATA_SECRET;
export const pinFileToIPFS = async (filePath) => {
const url = "https://api.pinata.cloud/pinning/pinFileToIPFS";
//we gather a local file for this example, but any valid readStream source will work here.
let data = new FormData();
data.append('file',fs.createReadStream(filePath));
return axios.post(url,
data,
{
maxContentLength: 'Infinity', //this is needed to prevent axios from erroring out with large files
headers: {
'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
'pinata_api_key': key,
'pinata_secret_api_key': secret
}
})
.then(function (response) {
//handle response here
return {
success: true,
pinataUrl: "https://gateway.pinata.cloud/ipfs/" + response.data.IpfsHash
};
})
.catch(function (error) {
//handle error here
console.log(error)
return {
success: false,
message: error.message,
}
});
};
How to fix it Or Is there any way of doing this rather than using 'fs'?
'fs' package has been deemed as malicious software, from github security placeholder page: "This package contained malicious code and was removed from the registry by the npm security team...". I wouldn't recommend using it.
The error message is specifying (TypeError): fs.createReadStream is not a function.
While doing research, I found fs-extra npm package is a good replacement for fs.
With fs-extra, you can use the readJson (one of many methods) method executing it with a callback, promises, or async/await e.g.:
const fse = require('fs-extra');
...
try {
const fileObject = await fse.readJson(filePath);
data.append('file', fileObject);
console.log(fileObject);
} catch (err) {
console.error(err);
}
...
If this is doesn't work, based on this node.js example attempt the following:
Create a variable with the createReadStream method:
// This line opens the file as a readable stream
let readStream = fs.createReadStream(filePath);
Use the following as intended to retrieve the response and catch any errors
// This will wait until we know the readable stream is actually valid before piping
readStream.on('open', function () {
// This just pipes the read stream to the response object (which goes to the client)
readStream.pipe(res);
// in your case:
data.append('file', res);
});
// This catches any errors that happen while creating the readable stream (usually invalid names)
readStream.on('error', function(err) {
res.end(err);
});

Proxy error: Could not proxy request /payment from localhost:3000 to https://localhost:5000/

I am trying to create a stripe payment app using reactJS and expressJS, I am getting this error:
Proxy error: Could not proxy request /payment from localhost:3000 to https://localhost:5000/
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (EPROTO)
In package.json file I have set proxy as -
"proxy": "https://localhost:5000"
In my react component I have -
const onToken = token => {
axios({
url: "payment",
method: "post",
data: {
amount: priceForStripe,
token: token
}
})
.then(response => {
alert("succesful payment");
})
.catch(error => {
console.log("Payment Error: ", error);
alert(
"There was an issue with your payment! Please make sure you use the provided credit card."
);
});
};
In my server.js I have -
const stripe = require("stripe")("sk_test_...");
app.post("/payment", (req, res) => {
const body = {
source: req.body.token.id,
amount: req.body.amount,
currency: "usd"
};
stripe.charges.create(body, (stripeErr, stripeRes) => {
if (stripeErr) {
res.status(500).send({ error: stripeErr });
} else {
res.status(200).send({ success: stripeRes });
}
});
});
whenever I submit any payment I hit error -
I tried all method linked here but can't solve that issue. I heartily thank if anyone explain any solution of that problem.
Since your backend works fine without stripe, the 500 error indicates that stripe is the problem.
This is related to the information you are sending in the body of the stripe charges.create request. I think you are missing the customer.id.
This post arjunphp.com/node-stripe-express-js shows the charges.create request as
{ amount,
description: "Sample Charge",
currency: "usd",
customer: customer.id
}
As #CherryDT mentioned, first I set proxy to "proxy": "http://localhost:5000". Then I change my backend code as #Greg M suggested -
app.post("/payment", (req, res) => {
stripe.customers
.create({
email: req.body.email, // customer email, which user need to enter while making payment
source: req.body.token.id // token for the given card
})
.then(customer =>
stripe.charges.create({
// charge the customer
amount: req.body.amount,
description: "Sample Charge",
currency: "usd",
customer: customer.id
})
)
.then(charge => res.status(200).send({ success: "success" }));
});
That's it. My payment method works perfectly.
I think the proxy error is a red herring. The real issue is the parsing on your server, causing the 500.
It looks like by default Axios encodes the json for you (but you should double check the request). To access JSON encoded request body data in Express, you need to use the body-parser middleware.
See this answer for an example: How do I consume the JSON POST data in an Express application
I'm taking the exact react course from Andre. My solution was to start the backend server.
So whoever gets into this issue from the same course either try the answer above or:
npm start
or
yarn start

Protractor async/await UnhandledPromiseRejectionWarning: Unhandled promise rejection

So I'm migrating my protractor tests using the async/await(Link).
Migration is somewhat successful so far until I keep running into this issue.
So following are steps of my test followed by code as an example of what I'm dealing with :
Navigates to a particular page
changes the context (Changing school to High school)
Grabs High school room list
Change context again (Changing school to Middle School)
Grab Middle school room list
Compare both lists
Related code for steps above:
Test.ts
describe("Update room list based on changing context values", () => {
let page: HelperClass;
let highSchoolRoomNameList: string[] = [];
let middleSchoolRoomNameList: string[] = [];
beforeAll(async () => {
page = new HelperClass();
await page.setBrowserSize();
await page.commonContextTestSteps();
});
it("Changing school dropdown value", async () => {
await page.waitForElement(page.schoolDropDown, 5000);
await page.schoolDropDown.click();
await page.waitForElement(page.dropDownList, 5000);
await page.dropDownList.get(0).click();
await browser
.switchTo()
.frame(element(by.tagName("iframe")).getWebElement());
await page.roomList.each( item => {
item.getAttribute("innerText").then(text => {
highSchoolRoomNameList.push(text);
});
});
await page.waitForElement(page.schoolDropDown, 5000);
await page.schoolDropDown.click();
await page.waitForElement(page.dropDownList, 5000);
await page.dropDownList.get(1).click();
await browser.switchTo().defaultContent();
await browser
.switchTo()
.frame(element(by.tagName("iframe")).getWebElement());
await page.roomList.each(item => {
item.getAttribute("innerText").then(text => {
middleSchoolRoomNameList.push(text);
});
});
await protractor.promise.controlFlow().execute(() => {
expect(highSchoolRoomNameList).not.toEqual(middleSchoolRoomNameList);
});
});
});
I keep getting this error :
(node:13672) UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 1): StaleElementReferenceError: stale element
reference: element is not attached to the page document (Session
info: chrome=65.0.3325.181) (Driver info: chromedriver=2.38.552522
(437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb),platform=Windows NT
6.1.7601 SP1 x86_64) (node:13672) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise
rejections that are not handled will terminate the Node.js process
with a non-zero exit code. (node:13672)
UnhandledPromiseRejectionWarning: Unhandled promise rejection
(rejection id: 2): StaleElementReferenceError: stale element
reference: element is not attached to the page document (Session
info: chrome=65.0.3325.181)
after debugging I found out it fails at the following steps
await browser
.switchTo()
.frame(element(by.tagName("iframe")).getWebElement());
await page.roomList.each( item => {
item.getAttribute("innerText").then(text => {
highSchoolRoomNameList.push(text);
});
});
The whole test used to work fine before I started to migrate towards async/await. This is my protractor.conf.js file :
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require("jasmine-spec-reporter");
exports.config = {
SELENIUM_PROMISE_MANAGER: false,
allScriptsTimeout: 11000,
suites: {
navigation_suite: "./nav-wrapper/e2e/nav-wrapper-navigationTests/**/*.ts"
},
specs: [
"Test.ts"
],
capabilities: {
browserName: "chrome"
},
directConnect: true,
baseUrl: "http://localhost:3000",
framework: "jasmine",
jasmineNodeOpts: {
showColors: true,
// Set a longer Jasmine default Timeout for debugging purposes
defaultTimeoutInterval: 999999,
print: function() {}
},
onPrepare() {
require("ts-node").register({
project: "./nav-wrapper/e2e/tsconfig.e2e.json"
});
jasmine
.getEnv()
.addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
Any suggestions on how to rewrite those methods will be appreciated!
This is not a direct answer to the question of rewriting the methods however just wanted to help you get a better error than Unhandled promise rejection (which is not all that helpful)
Where you are using .then if you put a .catch() at the end of that sequence, you can do something with the error, like log it in the console. It's something you should do anyway but also will help you figure out what is causing the error here.
Here is an example of what I mean:
asyncFuncA.then(AsyncFuncB)
.then(AsyncFuncC)
.then(AsyncFuncD).catch(e => {
//Do something with the error here
console.error(e)
})
and an example of your code
await page.roomList.each((item) => {
item
.getAttribute('innerText')
.then((text) => {
highSchoolRoomNameList.push(text);
})
.catch((e) => {
console.error(e);
});
});
If you still have the same error. You may probably try the following snippet(slightly modified from yours):
await browser
.switchTo()
.frame(element(by.tagName("iframe")).getWebElement());
await page.roomList.each(async item => {
await item.getAttribute("innerText").then(text => {
highSchoolRoomNameList.push(text);
});
});

Open S3 Pre-Signed URL with window.location not working

I am trying to show an image or a document coming from an AWS S3 Pre-Signed URL in my react application. Following is my code.
this.props.getS3SignedURL(key).then(url=> {
this.setState({ isLoading: false, error: "", url: url});
window.location = url;
}, err => {
//err
});
It works without any issue in Google Chrome, it displays the document. But in Microsoft Edge and IE the location doesn't change.
I tried with encodeURI(), encodeURIComponent() and window.location.href all combinations. But can't get it to work in Edge and IE. I tried with google document viewer as mentioned here. Still it's not working, and I suspect whether I can user Google document viewer because the document coming from the url can be an image/pdf/xls etc.
Based on your comment about unhandled promise rejection, one thing I'd recommend is try the more common method of handling errors of a promise, like below:
this.props.getS3SignedURL(key)
.then(url => {
this.setState({ isLoading: false, error: "", url: url });
window.location = url;
})
.catch(err => {
console.log(err);
});
Other then that, you may want to check that it's not a SOP issue or a CORS issue.

How to mock $.ajax call in JEST

I am new to React & JEST framework, I tried doing ajax call in react as below, if i receives a success data it will redirect to home page else an error message is displayed.
let params ={
userName : this.state.userName,
password : this.state.passWord
};
$.ajax({
url: '/reactApp/login',
dataType: 'json',
contentType: 'application/json;',
type: 'POST',
data: JSON.stringify(params),
success: function (successData) {
if (typeof(Storage) !== "undefined") {
localStorage.setItem('userProfile', JSON.stringify(successData));
browserHistory.push('/reactApp/Home');
} else {
alert("The browser version is not supported.Please use Internet explorer 11, Chrome or firefox.")
}
}.bind(this),
error: function(errorData){
this.setState({
errorMessage: errorData.message,
errorDisplay: true,
});
}.bind(this);
The react code is working, i tried to write an unit test in JEST for the above code for ajax call as below,
jest.unmock('jquery');
jest.unmock('./AjaxLogin');
var $ = require('jquery');
const Login = TestUtils.renderIntoDocument(<AjaxLogin />);
expect(Login).toBeDefined();
var handleClick = jest.genMockFunction();
var button = TestUtils.findRenderedDOMComponentWithTag(Login, 'button');
TestUtils.Simulate.click(button);
Login.handleClick();
expect($.ajax).toBeCalledWith({
url: '/reactApp/login',
dataType: 'json',
contentType: 'application/json;',
type: 'POST',
data: JSON.stringify({userName : 'testing', password : 'password'}),
success: jasmine.any(Function),
error: jasmine.any(Function)
});
When i run this test case, i received an below error message, i don't know what is wrong in the above code.
Expected Function to be called with Object
can anyone please help me to identify the issue in unit test script.
unmock method removes mock so you need to use Jest mock method instead.
Jest repo has several examples describing the basic usage including how to mock jquery as well as how to use with react so it is worth looking at.

Resources