Passing custom Chrome profile directory when starting Cypress - javascript

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

Related

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

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

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>
...
';

Create React App not reusing existing tab

I have been developing a web app (for a few months) that is built on top of CRA. Everything has been working as intended until this morning when I realized that the npm (or yarn) start script is no longer reusing the existing tab I have open in Chrome. It instead opens a new tab at localhost:3000 even if there are existing tabs at localhost:3000. I have been investigating this for a few hours but am yet to find a solution. I added a log statement in the CRA script (within my node modules) that handles the reusing of existing tabs upon startup of the app.
function startBrowserProcess(browser, url) {
// If we're on OS X, the user hasn't specifically
// requested a different browser, we can try opening
// Chrome with AppleScript. This lets us reuse an
// existing tab when possible instead of creating a new one.
const shouldTryOpenChromeWithAppleScript =
process.platform === 'darwin' &&
(typeof browser !== 'string' || browser === OSX_CHROME);
if (shouldTryOpenChromeWithAppleScript) {
try {
// Try our best to reuse existing tab
// on OS X Google Chrome with AppleScript
execSync('ps cax | grep "Google Chrome"');
execSync('osascript openChrome.applescript "' + encodeURI(url) + '"', {
cwd: __dirname,
stdio: 'ignore',
});
return true;
} catch (err) {
console.log(err);
// Ignore errors.
}
}
This is the output of the log statement:
{ Error: Command failed: osascript openChrome.applescript "http://localhost:3000/"
at checkExecSyncError (child_process.js:621:11)
at execSync (child_process.js:658:13)
at startBrowserProcess (/Users/***/Desktop/WorkSpace/React/***/node_modules/react-dev-utils/openBrowser.js:78:7)
at openBrowser (/Users/***/Desktop/WorkSpace/React/***/node_modules/react-dev-utils/openBrowser.js:122:14)
at Server.devServer.listen.err (/Users/***/Desktop/WorkSpace/React/***/node_modules/react-scripts/scripts/start.js:100:7)
at Server.returnValue.listeningApp.listen (/Users/***/Desktop/WorkSpace/React/***/node_modules/webpack-dev-server/lib/Server.js:604:10)
at Object.onceWrapper (events.js:273:13)
at Server.emit (events.js:182:13)
at emitListeningNT (net.js:1328:10)
at process.internalTickCallback (internal/process/next_tick.js:72:19)
status: 1,
signal: null,
output: [ null, null, null ],
pid: 2691,
stdout: null,
stderr: null }
It seems to have an issue running the Applescript command that handles this but I am unsure why. One of the other developers that is working on the same app locally is not having this issue. One change I made recently was upgrading to the new macOS Mojave. But the other developer just upgraded as well and is not having this issue.
Does anyone know what could be wrong?
To avoid opening a new tab,
you'll need to create an .env file in the root of your project and add this line,
BROWSER=none.
As shown here
Turns out after I upgraded Mojave I denied interface access to Google Chrome from my terminal. So it was unable to run the "reuse" tab script.

using console.log() with electron

I have seen a lot of questions from people trying to console log from the rendering process, this is NOT my problem I have console.log littering my main code and I don't see anything in my console here is my code.
/* eslint-disable no-undef */
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const url = require('url');
/* eslint-enable */
let win;
console.log('console log test');
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 800
});
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}));
win.on('close', () => {
win = null;
});
console.log('console log test');
}
app.on('ready', createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (win == null) {
console.log('console log test');
createWindow();
console.log('console log test');
}
});
I don't see a single log other than the ones produced by electron itself
I've tried throwing errors and those work fine but anything console.* related doesn't work at all, I've tried running it in PowerShell and re-pulling from GitHub, my friend can see the console logs when he pulls the project though so it seems I'm isolated. I've also updated NPM and all modules associated with the project AND I've tried creating a new console and logging to that one but it doesn't seem to show up, am I missing something? I've put hours into this and am ready to give up.
On Windows, if you want to see a console with all your messages from console.log(), you must launch your app with the parameter --enable-logging, for example :
MyApp.exe --enable-logging
I feel your pain. I have this issue on one of my boxes (a Server2012 box). Nothing worked for me until I stumbled across this comment on one of the electron issues threads.
Typically when you install electron you will have a script in your package.json that looks like this.
"scripts": {
"start": "electron .",
}
I changed mine to
"scripts": {
"start": "C:/path/to/project/node_modules/electron-prebuilt/dist/electron.exe .",
}
And I started to get logging from the main electron process in powershell.
Note that if you are using newer versions of electron, you may need to change electron-prebuilt to electron.
How about logging directly into the browser console?
I have found this to be easier for my workflow.
So what I do is to set a listener on the ipcRenderer to the main process and anytime I needed to log a thing from the main, I just emit to the listerner on the renderer.
For instance, in the renderer.js, I set up like so:
pre.ipcRenderer.on("log", (event,log) => {
console.log(log)
});
and in the main, wherever I need to log a piece of code, I just insert this line of code:
window.webContents.send("log", [__dirname]);
My Assumptions with the codes above:
You have set nodeIntegration: false in your webPreference object. This is why codes like __dirname will be unavailable on the renderer process.
As a result of the above, you are using a preloader to load all your required node-specific files.
I defined all of them in my preload.js file and ship them into one giant object which I named window.pre
One of the preloaded modules in the pre object is ipcRenderer. This is why I consumed it as pre.ipcRenderer
All of these is to say that, if you are consuming your nodes directly from the renderer process, you wont need to be bothered by my pre. and if not, now you now why I used it.
Ciao.

Webdriver.io crashes with NoSessionIdError

I'm trying to get webdriver.io and Jasmine working.
Following their example, my script is at test/specs/first/test2.js (in accordance with the configuration) and contains:
var webdriverio = require('webdriverio');
describe('my webdriverio tests', function() {
var client = {};
jasmine.DEFAULT_TIMEOUT_INTERVAL = 9999999;
beforeEach(function() {
client = webdriverio.remote({ desiredCapabilities: {browserName: 'firefox'} });
client.init();
});
it('test it', function(done) {
client
.url("http://localhost:3000/")
.waitForVisible("h2.btn.btn-primary")
.click("h2.btn.btn-primary")
.waitForVisible("h2.btn.btn-primary")
.call(done);
});
afterEach(function(done) {
client.end(done);
});
});
I'm using wdio as the test runner, and set it up using the interactive setup. That config is automatically-generated and all pretty straightforward, so I don't see a need to post it.
In another terminal window, I am running selenium-server-andalone-2.47.1.jar with Java 7. I do have Firefox installed on my computer (it blankly starts when the test is run), and my computer is running OS 10.10.5.
This is what happens when I start the test runner:
$ wdio wdio.conf.js
=======================================================================================
Selenium 2.0/webdriver protocol bindings implementation with helper commands in nodejs.
For a complete list of commands, visit http://webdriver.io/docs.html.
=======================================================================================
[18:17:22]: SET SESSION ID 46731149-79aa-412e-b9b5-3d32e75dbc8d
[18:17:22]: RESULT {"platform":"MAC","javascriptEnabled":true,"acceptSslCerts":true,"browserName":"firefox","rotatable":false,"locationContextEnabled":true,"webdriver.remote.sessionid":"46731149-79aa-412e-b9b5-3d32e75dbc8d","version":"40.0.3","databaseEnabled":true,"cssSelectorsEnabled":true,"handlesAlerts":true,"webStorageEnabled":true,"nativeEvents":false,"applicationCacheEnabled":true,"takesScreenshot":true}
NoSessionIdError: A session id is required for this command but wasn't found in the response payload
at waitForVisible("h2.btn.btn-primary") - test2.js:21:14
/usr/local/lib/node_modules/webdriverio/node_modules/q/q.js:141
throw e;
^
NoSessionIdError: A session id is required for this command but wasn't found in the response payload
0 passing (3.90s)
$
I find this very strange and inexplicable, especially considering that it even prints the session ID.
Any ideas?
Please check out the docs on the wdio test runner. You don't need to create an instance using init on your own. The wdio test runner takes care on creating and ending the session for you.
Your example covers the standalone WebdriverIO usage (without testrunner). You can find examples which use wdio here.
To clarify that: there are two ways of using WebdriverIO. You can embed it in your test system by yourself (using it as standalone / or as a scraper ). Then you need to take care of things like create and end an instance or run those in parallel. The other way to use WebdriverIO is using its test runner called wdio. The testrunner takes a config file with a bunch of information on your test setup and spawns instances updates job information on Sauce Labs and so on.
Every Webdriver command gets executed asynchronously.
You properly called the done callback in afterEach and in your test it test, but forgot to do it in beforeEach:
beforeEach(function(done) {
client = webdriverio.remote({ desiredCapabilities: {browserName: 'firefox'} });
client.init(done);
});

Categories