Using JSDOM in jest tests - jestjs

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

NodeJS Javascript - ChromeDriver - Script works fine in Windows. In Docker gives ElementNotFoundException

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?

Nestjs Repository test fails with error "Received promise resolved instead of rejected"

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);

How do I get a backtrace or otherwise debug "failed to initiate panic" when using Rust with Neon bindings?

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.

What is the Dockerfile to use node:12-alpine with puppeteer#1.19?

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.

Jest toThrow() method not capturing error

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?

Resources