I wanted to use JSDOM in my jest test suit. However, while JSDOM standalone works perfect, when i run it within jest test, it throws strange errors about encoding.
Look at that snippet
const { JSDOM } = require("jsdom");
describe("suit", () => {
test("test", () => {
JSDOM.fromURL("your_url", {}).then(dom => {
expect(1).toBe(1);
});
});
});
Snippet above depending on the your_url throws Error: Encoding not recognized: 'ISO-8859-2' (searched as: 'iso88592') ( for example https://gazeta.pl ) or Error: Encoding not recognized: 'UTF-8' (searched as: 'utf8') ( for example https://github.com). There is no url i was able to make it working, always one out of two errors described above. However when you run :
const { JSDOM } = require("jsdom");
JSDOM.fromURL("https://example.com/", {}).then(dom => {
console.log(dom.serialize());
});
it works as it should. Reproduction repo : https://github.com/pociej/jsdom_problem_reproduction.
environment info :
System:
OS: macOS Mojave 10.14.3
CPU: (4) x64 Intel(R) Core(TM) i7-4578U CPU # 3.00GHz
Binaries:
Node: 12.14.0 - ~/.nvm/versions/node/v12.14.0/bin/node
Yarn: 1.21.1 - /usr/local/bin/yarn
npm: 6.13.4 - ~/.nvm/versions/node/v12.14.0/bin/npm
npmPackages:
jest: ^24.9.0 => 24.9.0
full error listing :
npm test
> test_jsdom#1.0.0 test /Users/grzegorz/Projects/Meteor/playground/test_jsdom
> jest
PASS __tests__/test.js
suit
✓ test (35ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.93s
Ran all test suites.
(node:13599) UnhandledPromiseRejectionWarning: Error: Encoding not recognized: 'ISO-8859-2' (searched as: 'iso88592')
(node:13599) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:13599) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated.
Related
I have an automation script which is in NodeJS JavaScript which uses chromedriver and selenium-webdriver. It runs perfectly fine in Windows but in Docker container it gives ElementNotFoundException. The chrome version and chromedriver version matches.
Following is the JavaScript file:
require("chromedriver");
const {By,Key,Builder} = require("selenium-webdriver");
const chrome = require('selenium-webdriver/chrome');
async function functionA(){
const url = "abcd.com";
var cCode;
//To wait for browser to build and launch properly
let driver = await new Builder()
.forBrowser("chrome")
.setChromeOptions(new chrome.Options().addArguments(['--no-sandbox','--headless', '--disable-dev-shm-usage']))
.build();
await driver.get(url);
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
await wait(1 * 20 * 1000);
await driver.manage().window().setRect({ width: 1552, height: 840 });
await driver.findElement(By.id("email")).click();
await driver.findElement(By.id("email")).sendKeys("abcd");
var sName = await driver.findElement(By.id("email")).getText();
console.log("sName is: " + sName);
await driver.findElement(By.id("submitbutton")).click();
//this.timeout(1.33 * 20 * 1000);
await wait(1 * 20 * 1000);
//It is always a safe practice to quit the browser after execution
await driver.quit();
//console.log(cCode);
return 'some code;
}
async function testFunctionA()
{
var result = await functionA();
console.log(result);
}
testFunctionA();
Above script is called through a bash script.
#!/bin/bash
v=$(node ./test/executeScript.js)
echo "$v"
This shell script is called through docker:
FROM timbru31/node-chrome
USER root
RUN node --version
RUN npm --version
RUN apt-get update
RUN mkdir /data
COPY . /dataRUN npm --prefix /data install
RUN apt-get install -y apt-utils
RUN google-chrome --product-version
ADD /test /data/test
ADD /load-test /data/load-test
RUN ls -a
RUN SAUTH=$(sh /data/bashScript.sh)
Now when I run this docker file, I get the following exception
(node:8) UnhandledPromiseRejectionWarning: NoSuchElementError: no such element: Unable to locate element: {"method":"css selector","selector":"*[id="emailInput"]"}
(Session info: headless chrome=96.0.4664.93)
at Object.throwDecodedError (/data/node_modules/selenium-webdriver/lib/error.js:517:15)
at parseHttpResponse (/data/node_modules/selenium-webdriver/lib/http.js:643:13)
at Executor.execute (/data/node_modules/selenium-webdriver/lib/http.js:569:28)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async Driver.execute (/data/node_modules/selenium-webdriver/lib/webdriver.js:732:17)
at async toWireValue (/data/node_modules/selenium-webdriver/lib/webdriver.js:140:15)
at async /data/node_modules/selenium-webdriver/lib/webdriver.js:190:16
at async forEachKey (/data/node_modules/selenium-webdriver/lib/webdriver.js:184:9)
at async convertKeys (/data/node_modules/selenium-webdriver/lib/webdriver.js:189:3)
at async Driver.execute (/data/node_modules/selenium-webdriver/lib/webdriver.js:730:22)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:8) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:8) [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.
Command-line options | Node.js v17.2.0 Documentation
Please note that the javascript works perfectly fine in windows. All issues are encountered in docker.
What could be the possible reason and solution to resolve this issue?
I am writing unit tests for my backend application, I am struggling to test for a item in the database not being found, this is the code for my repository to be tested:
#EntityRepository(Collectible)
export class CollectibleRepository extends Repository<Collectible> {
async getCollectible(id: number) {
const collectible = await this.findOne(id);
if (!collectible) {
throw new NotFoundException();
}
return collectible;
}
}
And this is the code for testing, I will only show this test case.
const mockCollectible = new Collectible(
faker.lorem.sentence(),
faker.lorem.sentences(3),
faker.datatype.float(),
faker.datatype.float(),
faker.datatype.number(),
);
describe('Collectible Repository', () => {
let collectibleRepository: CollectibleRepository;
beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [CollectibleRepository],
}).compile();
collectibleRepository = module.get<CollectibleRepository>(
CollectibleRepository,
);
});
describe('View Collectibles', () => {
it('throws and error as the collectible is not found', async (done) => {
collectibleRepository.findOne = jest.fn().mockResolvedValue(undefined);
await expect(collectibleRepository.getCollectible(1)).rejects.toThrow(
NotFoundException,
);
done();
});
});
});
This causes the following error output:
Expected message: not "Not Found"
8 | const collectible = await this.findOne(id, { relations: ['business'] });
9 | if (!collectible) {
> 10 | throw new NotFoundException();
| ^
11 | }
12 | return collectible;
13 | }
at CollectibleRepository.getCollectibleBusiness (src/collectible/collectible.repository.ts:10:13)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:95012) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:95012) [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.
FAIL src/collectible/collectible.repository.spec.ts (8.525 s)
● Collectible Repository › View Collectibles › throws and error as the collectible is not found
expect(received).rejects.not.toThrow()
Received promise resolved instead of rejected
Resolved to value: undefined
39 | it('throws and error as the collectible is not found', async (done) => {
40 | collectibleRepository.findOne = jest.fn().mockResolvedValue(undefined);
> 41 | await expect(collectibleRepository.getCollectible(1)).rejects.not.toThrow(
| ^
42 | NotFoundException,
43 | );
44 | done();
at expect (../node_modules/expect/build/index.js:134:15)
at Object.<anonymous> (collectible/collectible.repository.spec.ts:41:13)
I tried using this repository (which was mentioned in another SO thread) with a set of examples for testing Nest.js applications, but it seems like a repository is not being directly tested.
Update: I updated my code since I was missing a await in my code (as noted by Micael Levi ), I was also calling the wrong function (lol). I am receiving the following warning:
(node:98378) UnhandledPromiseRejectionWarning: Error: expect(received).rejects.not.toThrow(expected)
Though probably I will ignore it unless it affects my CI pipeline (which I need to configure lmao)
Update 2: Warning was caused by another test (I may rest for now).
you missed the await in const collectible = this.findOne(id);
So
const collectible = await this.findOne(id);
I have written a native Node module using Rust + Neon Bindings. The general purpose is to query a database, decrypt the results, and return a JSON array to Node. For some datasets this is working as expected, however for others it is causing a panic. I am attempting to debug it, however I can't figure out how to get a stacktrace. The only output is:
fatal runtime error: failed to initiate panic, error 5
Abort trap: 6
My attempts to debug include:
including "backtrace" in the Cargo.toml
compiling without "--release"
setting RUST_BACKTRACE=1 and DEBUG=true
creating a test.js file to print the output from the module
Build output:
> neon build
neon info running cargo
... all the compilation steps.
Finished dev [unoptimized + debuginfo] target(s) in 2m 17s
neon info generating native/index.node
Test file:
const Addon = require('./lib');
const addon = new Addon();
(async function() {
console.log(`process.env.RUST_BACKTRACE = ${process.env.RUST_BACKTRACE}`);
const i = await addon.getData(237);
console.log(i, i.length)
}());
Test output:
> RUST_BACKTRACE=1 DEBUG=true node test.js
process.env.RUST_BACKTRACE = 1
fatal runtime error: failed to initiate panic, error 5
Abort trap: 6
For other values passed to addon.getData() I get back the JSON array of data as expected. The dataset that is failing is quite large so I haven't been able to determine any differences.
> rustc --version
rustc 1.38.0 (625451e37 2019-09-23)
> cargo --version
cargo 1.38.0 (23ef9a4ef 2019-08-20)
> node --version
v11.15.0
> neon version
0.3.1
I have implemented a synchronous version of the code, as well as asynchronous using this example. The async callback is converted into a Promise in ./lib/index.js. After updating the test.js to use the synchronous version of the code, I got the following output:
(node:45229) UnhandledPromiseRejectionWarning: Error: internal error in Neon module: called `Option::unwrap()` on a `None` value
I added a bunch of println!()s to my code and was able to find the error (a missing required property on a decrypted JSON object), but was never able to get a proper stack trace. It seems like Neon must be swallowing them in the async code.
I ran into the same issue as you do, and for me I got it resolved by processing the result properly by using the match clause and use this method to handle the error results, so the callback will properly generate a NodeJS error on my side.
some of my snippet:
use std::sync::{Arc, Mutex};
use crate::utils::convert_uids_map;
use neon::prelude::*;
use dgraph_tonic::{DgraphError, Mutation, MutationResponse};
use dgraph_tonic::sync::{Mutate};
pub struct MutateTask<M> where M: Mutate {
pub txn: Arc<Mutex<Option<M>>>,
pub mu: Mutation,
}
impl<M> Task for MutateTask<M> where M: Mutate + 'static {
type Output = MutationResponse;
type Error = DgraphError;
type JsEvent = JsValue;
fn perform(&self) -> Result<Self::Output, Self::Error> {
let mut mutex_guard = self.txn.lock().unwrap();
let txn = mutex_guard.as_mut();
match txn {
Some(t) => t.mutate(self.mu.clone()),
None => Err(DgraphError::EmptyTxn)
}
}
fn complete(self, mut ctx: TaskContext, result: Result<Self::Output, Self::Error>) -> JsResult<Self::JsEvent> {
match result {
Ok(x) => Ok(convert_uids_map(&mut ctx, &x.uids).unwrap().upcast()),
Err(e) => ctx.throw_error(format!("MutateTask Error - {:?}", e))
}
}
}
and then I got meaningful error to proceed:
(node:50781) UnhandledPromiseRejectionWarning: Error: MutateTask Error - GrpcError(CannotDoRequest(Status { code: Unknown, message: "key error: subject:\"_:dg.1759080630.67\" predicate:\"#timestamp\" object_value:<str_val:\"2020-04-28T02:22:19.570Z\" > : predicate \"#timestamp\": Has invalid characters" }))
(node:50781) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:50781) [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.
Since I faced puppeteer#1.13 error when printing pdf with lots of photos(at least need to renew the lock):
when running in Dev, there was exception:
(node:17) UnhandledPromiseRejectionWarning: Error: Page crashed!
at Page._onTargetCrashed (/usr/src/app/node_modules/puppeteer/lib/Page.js:176:24)
So I would like to use latest version of puppeteer#1.19. However, when I changed to use that, there is error :
Line239: await page.pdf({
path: TEMP_DIR + filename,
format: 'A4',
printBackground: true
});
printPdf() Error
Error: Protocol error (IO.read): Invalid parameters handle: string value expected
at /usr/src/app/node_modules/puppeteer/lib/Connection.js:183:56
at new Promise ()
at CDPSession.send (/usr/src/app/node_modules/puppeteer/lib/Connection.js:182:12)
at Function.readProtocolStream (/usr/src/app/node_modules/puppeteer/lib/helper.js:241:37)
at async Page.pdf (/usr/src/app/node_modules/puppeteer/lib/Page.js:988:12)
at async printPdf (/usr/src/app/puppeteer.js:239:9)
at async /usr/src/app/puppeteer.js:129:21
-- ASYNC --
at Page. (/usr/src/app/node_modules/puppeteer/lib/helper.js:111:15)
at printPdf (/usr/src/app/puppeteer.js:239:20)
at processTicksAndRejections (internal/process/task_queues.js:85:5)
at async /usr/src/app/puppeteer.js:129:21 {
message: 'Protocol error (IO.read): Invalid parameters handle: string value expected'
}
How can I prepare Dockerfile to support puppeteer#1.19 or solve this error? Thanks.
I am doing this:
expect(async () => {await doSomething()}).toThrow('myThrownErrorMessage');
but this throws an error in the terminal:
(node:12725) UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 575): Error: myThrownErrorMessage
Is this simply a case of node capturing the error before Jest does?