How to import npm packages in vs code webview extension development? - javascript

I want to use npm packages(latextoMathML) but when i use it on my webview it gives me error on running the extension that is: undefined refrence caught: package name(latextoXML) not defined.
i have tried through let / var / const with require method.
i wants to use in my js code under webview function.

You cannot import the npm package into webview in the usual way, for example like this:
var somelibrary = require('somelibrary')
Instead, you can load the package as local resource.
See the Webview API documentation and example code for a detailed explanation
To do this, follow these minimum steps:
when creating a new panel, enable scripts
const panel = vscode.window.createWebviewPanel(
'viewType',
'view name',
vscode.ViewColumn.One,
{
// Enable javascript in the webview
enableScripts: true
}
);
wrap the npm package path in a special vscode uri. This uri will actually contain this string: "vscode-resource://file///path-to-extension/node_modules/somelibrary/somelibrary.js"
const libraryPath = vscode.Uri.file(
path.join(extensionPath, 'node_modules', 'somelibrary', 'somelibrary.js')
);
const scriptUri = webview.asWebviewUri(libraryPath);
pass path when creating html panel structure
return '
...
<script src='$(scriptUri)'></script>
...
';

Related

Passing custom Chrome profile directory when starting Cypress

We would like to use a custom Chrome profile directory for our Cypress tests. The application we are testing uses a Web SQL database which needs to be loaded into the Chrome browser. We already tried this command which should be a valid chromium argument.
launchOptions.args.push('--user-data-dir=/Users/testuser/dev/chrome')
Our setup:
MacOs
Chrome v93
Cypress v8.3.0
Cypress Cucumber Preprocessor v4.1.0
The code we tried in our index.js (plugins folder):
const browserify = require('#cypress/browserify-preprocessor');
const cucumber = require('cypress-cucumber-preprocessor').default;
const resolve = require('resolve');
module.exports = (on, config) => {
const options = {
...browserify.defaultOptions,
typescript: resolve.sync('typescript', { baseDir: config.projectRoot }),
};
on('file:preprocessor', cucumber(options));
on('before:browser:launch', (browser = {}, launchOptions) => {
// `args` is an array of all the arguments that will
// be passed to browsers when it launches
console.log(launchOptions.args) // print all current args
launchOptions.args.push('--user-data-dir=/Users/testuser/dev/chrome')
launchOptions.args.push('--auto-open-devtools-for-tabs')
return launchOptions
})
};
This seems not to be working while the --auto-open-devtools-for-tabs command is working fine, but the custom profile is not loaded. Is this a known issue? Or can we debug to see what is happening?
update 24/9/2021
I see that the argument is passed to Chrome by Cypress, but Cypress overrides the Chrome profile path. Steps to reproduce:
Add launchOptions argument with --user-data-dir like mentioned above
Open Cypress dashboard (npx cypress open)
Run 1 test in Chrome
Chrome browser opens, type chrome://version/ in URL bar
--user-data-dir=/Users/testuser/dev/chrome is listed in the Command Line panel, but I also see --user-data-dir=/Users/xxxxx/Library/Application Support/Cypress/cy/production/browsers/chrome-stable/interactive listed, and that is the Profile Path which is being used by Cypress
According to this thread I understand that this is how Cypress works https://github.com/cypress-io/cypress/issues/3671

How do I open a file saved in the user directory using Electron's Shell API

I'd like an Electron app to natively open a file stored in the User directory, with the path as %userprofile%/Documents/Dir1/ThisFile.txt.
From Electron's Shell Documentation:
const { shell } = require('electron')
shell.openPath('%userprofile%/Documents/Dir1/ThisFile.txt')
yields an error:
Windows cannot find '%userprofile%/Documents/Dir1/ThisFile.txt'. Make sure you typed the name correctly and try again.
I have also tried using:
shell.openPath(path.relative('./','%userprofile%/Documents/Dir1/ThisFile.txt')); which results in the same error.
What am I doing wrong? Is there a way to open a file stored in %userprofile%.
Use electron's cross-platform .getPath() method for that:
const path = require("path");
const { app, shell } = require("electron");
shell.openPath(path.join(app.getPath("documents"), "Dir1", "ThisFile.txt"));
See here: https://www.electronjs.org/docs/api/app#appgetpathname

failed to leave a valid exports object in titanium 9.0.1

I have added screenshot which i am getting error while building app for titanium
SDK : 9.0.1
For SDK 8.3.1 and 7.4.2 this error not coming app is working fine for this SDK version only having issue for 9.0.1
// requires:
// Set up device detector
var DeviceDetectClass = require('DeviceDetect');
var deviceDetect = new DeviceDetectClass();
this we importing in app.js
Implicit global functions do no longer work in Titanium 9.0.0.GA or higher. Best way to fix this is put those functions in a standalone JS file, and require them in at the place you want to use them.
So secondfile.js
function checkNetworkStatus() {
}
module.exports = {
checkNetworkStatus: checkNetworkStatus
}
Elsewhere in your app:
require('secondfile').checkNetworkStatus();
Another way is to put global functions like this in app.js. This is however not the recommended way.
global.checkNetworkStatus = functon() {}
Elsewhere in your app
checkNetworkStatus();

template node local library import

I have to setup a, most of the time, offline installation of Node-RED and need to use the "Chart.js" Library in a template node. Currently my working approach is to copy the Chart.js dictory to node-red-dashboard/dist/js and import it with <script src= "js/chart.js/dist/Chart.min.js"></script>. But when I want to update the dashboard I need to copy everything again. So it would be nice to have a permanent Solution for this.
I tryed two other approaches until now. For both I installed Chart.js to the .node-red dictory.
First I tryed it like this:
var canvas = document.getElementById('myChart').getContext('2d');
var ChartJs = require('Chart.js');
var chart = new ChartJs(canvas, {... }
in a script tag (... stands for the working chart code that is not edited), but it didn't work aswell as to put
functionGlobalContext: {chartjs:require('Chart.js')} into settings.js and change require('Chart.js') to global.get('chartjs')
Does anyone here has an Idea to solve this properly? Unfortunately the node throws no Error to the console so I don't get an idea whats wrong here.
Thanks in advance for every hint or solution,
manni
When I want to use any 3rd party charting library in my node-red dashboard, I put 2 ui_template nodes into my flow:
under "Template Type" select the "Added to site <head> section" and add the link to the library's url:
<script src="url/to/library.js"></script>
(which in your offline case would be a local url)
use the library's exported objects directly within the template, without using require, such as:
<div id="myChart"></div>
<script>
var canvas = document.getElementById('myChart').getContext('2d');
var chart = new ChartJs(canvas, { ... }
</script>
The trick is to have your local node-red instance serve the ChartJS library through a local url. For that, first add this require path line to the settings.js file, before the exports section:
// The `https` setting requires the `fs` module. Uncomment the following
// to make it available:
var fs = require("fs");
var path = require ("path");
then, uncomment the httpStatic section below that, within the exports:
// When httpAdminRoot is used to move the UI to a different root path, the
// following property can be used to identify a directory of static content
// that should be served at http://localhost:1880/.
httpStatic: path.join(__dirname, 'public'),
(you can use any directory name, in place of public) The __dirname references the node-red server's working directory, usually .node-red under your home directory.
Create this new public directory, copy the ChartJS files under it, and restart node-red. At startup, you should see a line in the console log showing the path to your new static file location:
5 Feb 12:12:23 - [info] Settings file : C:\NODE\node_red_ui\settings.js
5 Feb 12:12:23 - [info] HTTP Static : C:\NODE\node_red_ui\public
5 Feb 12:12:23 - [info] User directory : C:\NODE\node_red_ui
Now you can serve the local file public\scripts\abc.js using the local url
http://localhost:1880/scripts/abc.js
This way, npm updates to the dashboard code will not overwrite your static files.

How to probe if a file was download using Selenium/WebdriverIO

I want to know how I can verify if a file was downloaded using Selenium Webdriver after I click the download button.
Your question doesn't say whether you want to confirm it locally or remotely(like browserstack) . If it is remotely then my answer will be "NO" as you can see that the file is getting downloaded but you can not access the folder. So you wont be able to assert that the file has been downloaded.
If you want to achieve this locally(in Chrome) then the answer is "YES", you can do it something like this:
In wdio.conf.js(To know where it is getting downloaded)
var path = require('path');
const pathToDownload = path.resolve('chromeDownloads');
// chromeDownloads above is the name of the folder in the root directory
exports.config = {
capabilities: [{
maxInstances: 1,
browserName: 'chrome',
os: 'Windows',
chromeOptions: {
args: [
'user-data-dir=./chrome/user-data',
],
prefs: {
"download.default_directory": pathToDownload,
}
}
}],
And your spec file(To check if the file is downloaded or not ?)
const fsExtra = require('fs-extra');
const pathToChromeDownloads = './chromeDownloads';
describe('User can download and verify a file', () =>{
before(() => {
// Clean up the chromeDownloads folder and create a fresh one
fsExtra.removeSync(pathToChromeDownloads);
fsExtra.mkdirsSync(pathToChromeDownloads);
});
it('Download the file', () =>{
// Code to download
});
it('Verify the file is downloaded', () =>{
// Code to verify
// Get the name of file and assert it with the expected name
});
});
more about fs-extra : https://www.npmjs.com/package/fs-extra
Hope this helps.
TL;DR: Unless your web-app has some kind of visual/GUI trigger once the download finishes (some text, an image/icon-font, push-notification, etc.), then the answer is a resounding NO.
Webdriver can't go outside the scope of your browser, but your underlying framework can. Especially if you're using NodeJS. :)
Off the top of my head I can think of a few ways I've been able to do this in the past. Choose as applicable:
1. Verify if the file has been downloaded using Node's File System (aka fs)
Since you're running WebdriverIO, under a NodeJS environment, then you can make use its powerful lib tool-suite. I would use fs.exists, or fs.existsSync to verify if the file is in the expected folder.
If you want to be diligent, then also use fs.statSync in conjunction with fs.exists & poll the file until it has the expected size (e.g.: > 2560 bytes)
There are multiple examples online that can help you put together such a script. Use the fs documentation, but other resources as well. Lastly, you can add said script inside your it/describe statement (I remember your were using Mocha).
2. Use child_process's exec command to launch third-party scripts
Though this method requires more work to setup, I find it more relevant on the long run.
!!! Caution: Apart from launching the script, you need to write a script in a third-party framework.
Using an AutoIT script;
Using a Sikuli script;
Using a TestComplete (not linking it, I don't like it that much), or [insert GUI verification script here] script;
Note: All the above frameworks can generate an .exe file that you can trigger from your WebdriverIO test-cases in order to check if your file has been downloaded, or not.
Steps to take:
create one of the stand-alone scripts like mentioned above;
place the script's .exe file inside your project in a known folder;
use child_process.exec to launch the script and assert its result after it finishes its execution;
Example:
exec = require('child_process').exec;
// Make sure you also remove the .exe from scriptName
var yourScript = pathToScript + scriptName;
var child = exec(yourScript);
child.on('close', function (code, signal) {
if (code!==0) {
callback.fail(online.online[module][code]);
} else {
callback();
}
});
Finally: I'm sure there are other ways to do it. But, your main take-away from such a vague question should be: YES, you can verify if the file has been downloaded if you absolutely must, expecially if this test-case is CRITICAL to your regression-run.

Categories