Jest test doesn't create the files the normal program would - node.js

I'm using node and puppeteer to load a page, get its content and then create a screenshot if it. At the end of the run function I have the following lines
var content = fs.writeFileSync(outputFilePath, processedContent);
var screenshot = page.screenshot({path: '../output/whatever.png', fullPage:true})
browser.close();
This works when running the node app. For testing I am using JEST
And when trying to run the JEST test that checks for the screenshot:
it('Run should take a screenshot', async() => {
const runResult = await run();
const screenshot = fs.readFileSync('/app/output/whatever.png');
expect(screenshot).toBeTruthy();
})
I get the following error ENOENT: no such file or directory, open '/app/output/whatever.png'
I'm having a hard time understanding why in the normal app flow the program creates the files when running but in the tests it doesn't. As additional info the entire thing runs in a Docker container

It is most likely because you are using an absolute path instead of a relative path in your jest test.
So instead of
const screenshot = fs.readFileSync('/app/output/whatever.png');
write
const screenshot = fs.readFileSync('./app/output/whatever.png');
to use a relative path
Also keep in mind your relative path should be from the the project root

Related

React, Web3.js & Metaplex: Unable to import `programs.metadata.Metadata` from #metaplex/js

Issue
Attempting to follow the 'your first request' example here: https://docs.metaplex.com/sdk/js/getting-started#your-first-request
The module referred to in the examples doesn't contain the data needed.
For context, I am using this example to develop the solution explained at step 5 of these instructions: https://gist.github.com/creativedrewy/9bce794ff278aae23b64e6dc8f10e906
Steps to replicate
Step 1) I install the #metaplex/js package via: yarn add #metaplex/js
Step 2) I import programs from the module by placing import { programs } from '#metaplex/js';.
Step 3) I attempt to unpack Metadata from programs via: const { Metadata } = programs.metadata;
At this stage, if I execute npm run start or yarn run start I see the error that the property Metadata of programs.metadata is undefined. When I look in node_modules/#metaplex/js/ I see that the error is correct.
The only mention of metadata in the module is the function used to lookup metadata once you have the URL. The stage I am at is attempting to retrieve the URL, so this package is not useful, despite being the only one referred to in the docs.
To solve the issue, I created an empty react app and added the following dependencies to my package.json file:
"#metaplex/js": "^1.1.1",
"#solana/spl-token": "^0.1.8",
"#solana/web3.js": "^1.24.1",
I then ran npm install inside the app's root directory.
Inside App.js (or index.js if you did not use create-react-app), I unpacked Metadata directly from the metaplex package with the following line, placed at the top of the file:
import { Metadata } from '#metaplex/js';
Beneath all the imports, I added the following code (an edited version of the code from the example in the original question):
const connection = new Connection('devnet');
const tokenPublicKey = 'Gz3vYbpsB2agTsAwedtvtTkQ1CG9vsioqLW3r9ecNpvZ';
const run = async () => {
try {
const ownedMetadata = await Metadata.load(connection, tokenPublicKey);
console.log(ownedMetadata);
} catch {
console.log('Failed to fetch metadata');
}
};
In my implementation, I'm using a button inside my App() function, instead of calling run() directly like in the example:
<button
onClick={run}
>
GALLERY
</button>
Now, when clicking the button, I correctly see the metadata JSON displayed in the console.

Uploading a file with WebdriverIO and Cucumber

I'm doing some simple automation scripts using WDIO and Cucumber. I'm using test website for "uploading a file" example. I was looking for some solutions but no help was satisfactory.
I tried to follow these steps:
https://webdriver.io/docs/api/browser/uploadFile.html
https://webdriver.io/blog/2019/06/25/file-upload.html
My final "When" step looks like:
When('I pick example file from path', () => {
const input = Upload.fileUpload
const submitBtn = Upload.fileSubmit
const filePath = path.join(__dirname, '/file_path_on_desktop/');
const remoteFilePath = browser.uploadFile(filePath);
input.setValue(remoteFilePath);
submitBtn.click()
});
And I have received error
ENOENT: no such file or directory, open '/path_to_project_folder/file_path_on_desktop/'
which is weird.
Maybe I just did smth wrong due to Cucumber, or it's just not supported with Cucumber? However I tried without it and I also had same issue.
Error shown at this line
const remoteFilePath = browser.uploadFile(filePath);
I've got a solution.
Maybe I missed it somewhere, but in that case, __dirname shouldn't be here.
Or move the file from desktop to repository folder, then __dirname may stay as it is.

How to bundle and require non JS dependencies in Firebase Cloud Functions?

I have an http cloud function that returns some dynamic HTML. I want to use Handlebars as the templating engine. The template is sufficiently big that it's not practical to have it in a const variable on top of my function.
I've tried something like:
const template = fs.readFileSync('./template.hbs', 'utf-8');
But when deploying the function I always get an error that the file does not exist:
Error: ENOENT: no such file or directory, open './template.hbs'
The template.hbs is in the same directory as my index.js file so I imagine the problem is that the Firebase CLI is not bundling this file along the rest of files.
According to the docs of Google Cloud Functions it is possible to bundle local modules with "mymodule": "file:mymodule". So I've tried creating a templates folder at the root of the project and added "templates": "file:./templates" to the package.json.
My file structure being something like this:
/my-function
index.js
/templates
something.hbs
index.js //this is the entry point
And then:
const template = fs.readFileSync('../node_modules/templates/something.hbs', 'utf-8');
But I'm getting the same not found error.
What is the proper way of including and requiring a non JS dependencies in a Firebase Cloud Function?
The Firebase CLI will package up all the files in your functions folder, except for node_modules, and send the entire archive to Cloud Functions. It will reconstitue node_modules by running npm install while building the docker image that runs your function.
If your something.hbs is in /templates under your functions folder, you should be able to refer to it as ./templates/something.hbs from the top-level index.js. If your JS is in another folder, you might have to work you way out first with ../templates/something.hbs. The files should all be there - just figure out the path. I wouldn't try to do anything fancy is your package.json. Just take advantage of the fact that the CLI deploys everything but node_modules.
This code works fine for me if I have a file called 'foo' at the root of my functions folder:
import * as fs from 'fs'
export const test = functions.https.onRequest((req, res) => {
const foo = fs.readFileSync('./foo', 'utf-8')
console.log(foo)
res.send(foo)
})
The solution was to use path.join(__dirname,'template.hbs').
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join(__dirname,'template.hbs'), 'utf-8');
As #doug-stevenson pointed out all files are included in the final bundle but for some reason using the relative path did not work. Forcing an absolute path with __dirname did the trick.

My cli engine(npm package) cant find path to read file when install on another folder

I am building an app that auto completes some type of file. When i run node index.js in the program folder i get the correct i results.
Although i want to make it an npm package that can work as a cli engine. For example i want to write the command generate and the code to produce the results.
In order to auto complete the file i have to read some data that i have stored in a .csv file that comes along with my program.
When i try to run generate command under another folder it can read that file.
I am very new to cli and i don't understand yet quite well how thing work.
Thanks in advance for the help.
Here is the code of my cli conversion.
#!/usr/bin/env node
const program = require("commander");
const {
predict
} = require("./classifier");
program.version("1.0.0").description("ESLint Rules Generator");
program
.command("generate")
.description("Generate ESLint Rules")
.action(() => {
predict();
});
program.parse(process.argv);
Here is the problematic line:
let str = fs.readFileSync("data_files/rules.csv", "utf-8");
This is the error i get: ENOENT: no such file or directory, open 'data_files/rules.csv'

Working when run, but not when built

Im on macOS. I am creating a simple electron app. When I run the app with electron . everything works perfectly with no errors. Now that my app is finished, I wanted to build and distribute it. So I setup electron-builder and I got that to work just fine. However, when I run the MyApp.app in the build folder, I get an error saying:
Uncaught Error: ENOENT: no such file or directory, scandir './img/'
I call scandir here:
const fs = require('fs');
var files = [];
fs.readdirSync("./img/").forEach(file => {
files.push(file);
})
Why is this working when I run it with node, but is not working in the build? How can I fix this issue?
Why is this working when I run it with node, but is not working in the
build? How can I fix this issue?
It's difficult to tell without having more information about the whole app's structure, it may depend on how your code is actually called or required from the html file.
Anyway, using the __dirname global variable to build the directory path usually solves this kind of problem. Please try:
const fs = require('fs');
const path = require('path');
var files = [];
fs.readdirSync(path.join(__dirname, 'img')).forEach(file => {
files.push(file);
});

Resources