This has its use in automating creation of new Chrome Profiles. I am using windows and this tends to work except that it launches Chrome.
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe --profile-directory="Profile 1"
I am just wondering if there is a way to do this so that I can create profiles faster as it uses a lot of CPU this way. Firefox creates profiles without launching them.
These profiles will be later used in Selenium
Thanks
You should use NodeJS and chrome headless to automate this. Please look at the below url
https://developers.google.com/web/updates/2017/04/headless-chrome
const chromeLauncher = require('chrome-launcher');
function createChromeProfile(profileName) {
return chromeLauncher.launch({
// port: 9222, // Uncomment to force a specific port of your choice.
chromeFlags: [
'--profile-directory="' + profileName + '"',
'--window-size=412,732',
'--disable-gpu',
'--headless'
]
});
}
createChromeProfile("Profile 1").then(chrome => {
console.log(`Chrome debuggable on port: ${chrome.port}`);
...
chrome.kill();
});
Related
I'm writing acceptance tests on node.js using webdriver.io with selenium standalone server with latest Google Chrome driver.
I need to check that flash elements are clickable, but browser keeps to show me "Restart Chrome to enable Adobe Flash Player".
I've seen article that shows how to make Chrome driver to see custom profile on local machine, but I can't understand how to use this with my standalone server, since it has poor examples for configuration.
Can you explain the correct way to enable Adobe flash player for selenium standalone server in webdriver.io?
I found that the following worked:
browserName: 'chrome',
'goog:chromeOptions' : {
args: ['enable-features=RunAllFlashInAllowMode',
'disable-features=EnableEphemeralFlashPermission'],
prefs: {
"profile.content_settings.exceptions.plugins.*,*.per_resource.adobe-flash-player": 1,
'PluginsAllowedForUrls': '/route/to/site.com'
}
}
Using ephemeral mode will create a temp profile which allows the prefs to take effect:
https://developer.chrome.com/extensions/contentSettings
https://support.google.com/chrome/a/answer/3538894?hl=en
'goog:chromeOptions' was introduced as of selenium 3.8 github.com/elgalu/docker-selenium/issues/201 –
You can open up the profile which is a JSON blob and see the site added at profile.content_settings.exceptions.plugins and profile.content_settings.exceptions.flash_data.
It is very easy. you need to create a custom profile that you will always use to load your chrome with. then you configure the browser like you would do manually too. this means make website exclusions for flash. load some extensions or whatever you want to preconfig. with this code you can do it
// setup browser
var options = {
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: {
args: ['user-data-dir=C:/Users/Administrator/AppData/Local/Google/Chrome/User Data/Profile 21v69',
'--lang=en']
} // chromeOptions: {
} // desiredCapabilities: {
} // options = {
var client = webdriverio.remote(options).init();
Also here are all command line commands for chrome
https://peter.sh/experiments/chromium-command-line-switches/
Another workable method. It's possible to allow flash plugin execution in the chrome config
You need to add in the wdio.conf.js three last preferences from code example
chromeOptions : {
args: chromeArgs,
prefs: {
"download.default_directory": process.env.PWD +'/download',
"profile.default_content_setting_values.plugins": 1,
"profile.content_settings.plugin_whitelist.adobe-flash-player": 1,
"profile.content_settings.exceptions.plugins.*,*.per_resource.adobe-flash-player": 1
}
}
I hope it will helpful
The Problem
I'm having an issue with a website (built w/ the Polymer Shop template) in production that's serving up old versions of code despite my new and improved deployments.
I'm using the Polymer CLI $ polymer build command along w/ the Firebase Tools $ firebase deploy command to push up changes to Firebase Hosting. After deploy is complete, I navigate to the website only to see the changes not updating:
Chrome: I see the old version of the website first and have to "hard refresh" for the changes to appear.
FireFox: I see the old version of the website first and have to "hard refresh" for the changes to appear.
Here's the before n' after shot:
Service Worker workflow?
I'm trying to figure out what the best workflow is for this. I want to set things up so that every time I make a new deploy, the entire site is wiped clean and the service worker resets itself through the inter webs and I'll be 100% sure that existing users will get that newly deployed experience
with out having to hard refresh or use incognito mode.
Should I...
Delete the service worker and deploy the new version without it (bad idea) ?
Create a "New Project" in the Firebase Console and re-link the custom domain up (tedious) ?
Find the "magic button" to press inside Firebase Console to reset (does this exist) ?
Edit the sw-precache-config.js file (not sure how) ?
Handle this in the $ polymer build to configure the sw-precache (not sure how) ?
Something awesome that don't even know about ¯\_(ツ)_/¯ ?
I know that the problem exists inside the sw-precache-config.js file, but I'm unsure if this is where I should be fixing this.
module.exports = {
staticFileGlobs: [
'/index.html',
'/manifest.json',
'/bower_components/webcomponentsjs/webcomponents-lite.min.js',
'/images/*'
],
navigateFallback: '/index.html',
navigateFallbackWhitelist: [/^(?!.*\.html$|\/data\/).*/],
runtimeCaching: [
{
urlPattern: /\/data\/images\/.*/,
handler: 'cacheFirst',
options: {
cache: {
maxEntries: 200,
name: 'items-cache'
}
}
},
{
urlPattern: /\/data\/.*json/,
handler: 'fastest',
options: {
cache: {
maxEntries: 100,
name: 'data-cache'
}
}
}
]
};
The Service Worker is an amazing tool and I definitely want it in my projects. I just need to learn how to tame the beast.
I don't know about polymer, but this is the flow I usually do with service workers.
- In the client I check if there is a update, the app notify the user if he/she wants to update.
- User accepts new version, then client send a message to sw to skipWating.
client.js:
navigator.serviceWorker.register('/serviceWorker.js').then(function(reg) {
reg.addEventListener('updatefound', function() {
reg.installing.addEventListener('statechange', function() {
if (reg.installing.state == 'installed') {
// Notify the user, there is a app new version.
// User accept
reg.installing.postMessage({msg: 'skipwaiting'});
}
});
});
});
-In the service worker listen for the message and skipWating if user accepts the new version.
serviceWorker.js:
self.addEventListener('message', function(event) {
if (event.data.msg === 'skipwaiting') {
self.skipWaiting();
}
});
The client refresh the application after the service worker has change state.
client.js:
let refreshing;
navigator.serviceWorker.addEventListener('controllerchange', function() {
if (refreshing)
return;
window.location.reload();
refreshing = true;
});
Maybe this can give you an idea.
I am trying to use an external process monitoring tool to alert me when my Chrome App dies. Unfortunately, all Chrome Apps seem to run inside their own chrome.exe process so there's no way to differentiate them in the monitoring tool. Is there any way to see which Chrome App is running in which process?
While this certainly is a manual solution (i.e. you won't be able to easily feed it into other tools), Chrome's built-in Task Manager (accessible via menu or Shift+Esc) allows you to correlate task (in this case, the App) to the system Process ID.
Whether it's possible from "outside" or using a command line call is still an open question.
One thing that can help distinguishing the process is that app processes always launch with --extension-process command line switch. But that doesn't allow you to tell which app (or extension) it is.
It's possible that if verbose enough logging is enabled, one would be able to parse the proccess ID from the logs.
I was finally able to do this using tasklist and looking for the window title which is set from the app name in manifest.json:
tasklist /FI "WINDOWTITLE eq MyChromeAppName" | find "chrome.exe"
For the purposes of the monitor, I wrapped it in a node.js function that the monitor app could use:
function chromeAppIsRunning(appName, cb){
var cmd = 'tasklist /FI "WINDOWTITLE eq ' + appName + '" | find "chrome.exe"';
childprocess.exec(cmd, function(err, stdout, stderr) {
stdout = (stdout || '').toLowerCase();
cb(stdout.indexOf('chrome.exe') > -1);
});
};
Then you can use it like this:
chromeAppIsRunning('MyApp', function(exists){
console.log('MyApp is running:', exists);
});
Hope that helps someone else
I have the following extremely simple Mocha / Chai test:
describe('main tests', function () {
var expect = chai.expect, something = null;
before(function () {
something = 0;
});
it('should equal 0', function () {
expect(something).to.equal(0);
});
});
This fails in chrome with the following output:
Error: global leaks detected: css, cssFile, cssRule
In both Firefox and Safari, it passes with no problem.
There was another global variable defined by Google's own Screen Capture extension. Upon disabling that extension Mocha only complained about css, cssFile, and cssRule being global leaks.
I checked and these variables are not defined in Safari or Firefox, so obviously something in Chrome or one of my Chrome extensions is defining these three variables. Is there any way to figure out which extension is defining these variables short of disabling and reenabling all of them in sequence?
The best solution for your problem is not some JavaScript snippet, but the source code of your installed extensions.
Visit the Extensions sub-directory of your Chrome profile (locations below).
Use a tool to recursively search for the term.
For example, using the grep command: grep -r 'cssFile' (available for Linux, Mac and even Windows).
Default locations for your profile's Chrome extensions
Windows XP:
Chrome : %AppData%\..\Local Settings\Application Data\Google\Chrome\User Data\Default\Extensions\
Chromium: %AppData%\..\Local Settings\Application Data\Chromium\User Data\Default\Extensions\
Windows Vista/7/8:
Chrome : %LocalAppData%\Google\Chrome\User Data\Default\Extensions\
Chromium: %LocalAppData%\Chromium\User Data\Default\Extensions\
Linux:
Chrome : ~/.config/google-chrome/Default/Extensions/
Chromium: ~/.config/chromium/Default/Extensions/
Mac OS X:
Chrome : ~/Library/Application Support/Google/Chrome/Default/Extensions/
Chromium: ~/Library/Application Support/Chromium/Default/Extensions/
Well, I just did the disable all extensions thing. Chrome Sniffer appears to be the culprit. Specifically in the following code (detector.js):
for (t in cssClasses) {
// snipped for brevity
for(css in cssClasses[t]) {
// snipped for brevity
for(cssFile in document.styleSheets) {
for(cssRule in document.styleSheets[cssFile].cssRules) {
// snipped for brevity
}
}
}
}
That will leak t, css, cssFile, and cssRule into global scope. Looks like I'm not the first to notice this: https://github.com/nqbao/chromesniffer/pull/51
If anybody wants to answer with how I could have avoided the manual process I will accept your answer.
I need to let users of an application open a folder by clicking a link inside a web page. The path of the folder is on the network and can be accessed from everywhere. I'm probably sure there is no easy way to do this, but maybe I'm mistaken?
Do you want to open a shared folder in Windows Explorer? You need to use a file: link, but there are caveats:
Internet Explorer will work if the link is a converted UNC path (file://server/share/folder/).
Firefox will work if the link is in its own mangled form using five slashes (file://///server/share/folder) and the user has disabled the security restriction on file: links in a page served over HTTP. Thankfully IE also accepts the mangled link form.
Opera, Safari and Chrome can not be convinced to open a file: link in a page served over HTTP.
The URL file://[servername]/[sharename] should open an explorer window to the shared folder on the network.
Using file:///// just doesn't work if security settings are set to even a moderate level.
If you just want users to be able to download/view files* located on a network or share you can set up a Virtual Directory in IIS. On the Properties tab make sure the "A share located on another computer" is selected and the "Connect as..." is an account that can see the network location.
Link to the virtual directory from your webpage (e.g. http://yoursite/yourvirtualdir/) and this will open up a view of the directory in the web browser.
*You can allow write permissions on the virtual directory to allow users to add files but not tried it and assume network permissions would override this setting.
A bit late to the party, but I had to solve this for myself recently, though slightly different, it might still help someone with similar circumstances to my own.
I'm using xampp on a laptop to run a purely local website app on windows. (A very specific environment I know). In this instance, I use a html link to a php file and run:
shell_exec('cd C:\path\to\file');
shell_exec('start .');
This opens a local Windows explorer window.
make sure your folder permissions are set so that a directory listing is allowed then just point your anchor to that folder using chmod 701 (that might be risky though)
for example
<a href="./downloads/folder_i_want_to_display/" >Go to downloads page</a>
make sure that you have no index.html any index file on that directory
What I resolved doing is installing a local web service on every person's computer that listens on port 9999 for example and opens a directory locally when told to. My example node.js express app:
import { createServer, Server } from "http";
// server
import express from "express";
import cors from "cors";
import bodyParser from "body-parser";
// other
import util from 'util';
const exec = util.promisify(require('child_process').exec);
export class EdsHelper {
debug: boolean = true;
port: number = 9999
app: express.Application;
server: Server;
constructor() {
// create app
this.app = express();
this.app.use(cors());
this.app.use(bodyParser.json());
this.app.use(bodyParser.urlencoded({
extended: true
}));
// create server
this.server = createServer(this.app);
// setup server
this.setup_routes();
this.listen();
console.info("server initialized");
}
private setup_routes(): void {
this.app.post("/open_dir", async (req: any, res: any) => {
try {
if (this.debug) {
console.debug("open_dir");
}
// get path
// C:\Users\ADunsmoor\Documents
const path: string = req.body.path;
// execute command
const { stdout, stderr } = await exec(`start "" "${path}"`, {
// detached: true,
// stdio: "ignore",
//windowsHide: true, // causes directory not to open sometimes?
});
if (stderr) {
throw stderr;
} else {
// return OK
res.status(200).send({});
}
} catch (error) {
console.error("open_dir >> error = " + error);
res.status(500).send(error);
}
});
}
private listen(): void {
this.server.listen(this.port, () => {
console.info("Running server on port " + this.port.toString());
});
}
public getApp(): express.Application {
return this.app;
}
}
It is important to run this service as the local user and not as administrator, the directory may never open otherwise.
Make a POST request from your web app to localhost: http://localhost:9999/open_dir, data: { "path": "C:\Users\ADunsmoor\Documents" }.
Does not work in Chrome, but this other answers suggests a solution via a plugin:
Can Google Chrome open local links?
You can also copy the link address and paste it in a new window to get around the security. This works in chrome and firefox but you may have to add slashes in firefox.
Hope it will help someone someday. I was making a small POC and came across this.
A button, onClick display contents of the folder. Below is the HTML,
<input type=button onClick="parent.location='file:///C:/Users/' " value='Users'>
I was looking for File System Access API and ended up in this question.
I know that API doesn't allow one to open an html link to a folder, but it does allow for opening local folders and files. For more information, take a look here:
https://web.dev/file-system-access/