Is it possible to set custom location coordinates with Chrome Headless? I can't find it in the
Devtools protocol
API. Is there a workaround available?
I googled it and got many methods. I try one by one, almost all of them turn out outdated. Then I find out a solution, use chrome devtools protocol to achieve that.
The small example code below, that it uses the most common tool selenium to execute chrome devtools protocol command.
import time
from selenium.webdriver import Chrome, ChromeOptions
options = ChromeOptions()
options.add_argument("--headless")
driver = Chrome(options=options)
driver.execute_cdp_cmd(
"Browser.grantPermissions",
{
"origin": "https://www.openstreetmap.org/",
"permissions": ["geolocation"]
},
)
driver.execute_cdp_cmd(
"Emulation.setGeolocationOverride",
{
"latitude": 35.689487,
"longitude": 139.691706,
"accuracy": 100,
},
)
driver.get("https://www.openstreetmap.org/")
driver.find_element_by_xpath("//span[#class='icon geolocate']").click()
time.sleep(3) # wait for the page full loaded
driver.get_screenshot_as_file("screenshot.png")
https://chromedevtools.github.io/devtools-protocol/tot/Emulation#method-setGeolocationOverride
and
https://chromedevtools.github.io/devtools-protocol/tot/Emulation#method-clearGeolocationOverride
... then you'll need to contend with ensuring that the correct location sharing setting is set within the user profile (chrome://settings/content/location - which is difficult to access due to being displayed via shadow dom, so using a preconfigured user profile will likely be easier --user-data-dir).
Edit to add: The above does not seem to be effective when using --headless. To resolve this I used https://chromedevtools.github.io/devtools-protocol/tot/Page#method-addScriptToEvaluateOnNewDocument with the following snippet:
navigator.geolocation.getCurrentPosition = function(success, failure) {
success({
coords: {latitude: <your_lat_float>, longitude: <your_lng_float>},
timestamp: Date.now(),
});
}
Related
I'm trying to make a Chrome extension that redirects to a pre defined page when a specified page is loaded.
I'm using webRequest for this, But now that I have to migrate to Manifest V3, webRequest can not be used anymore.
Can anyone help me with rewrite the script to make it work with Manifest V3?
Here's the script that I use to redirect pages:
var host = "http://example.com";
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {redirectUrl: host + details.url.match(/^https?:\/\/[^\/]+([\S\s]*)/)[1]};
},
{
urls: [
"*://foo.com/demo*",
"*://www.foo.com/test/*"
],
types: ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"]
},
["blocking"]
);
I would not recommend using declarativeNetRequest for this task, it is very limited in its capabilities and has an awkward interface.
It sounds like you want to redirect the user prior to the page being loaded. If that's the case, you need to hook into the request/response lifecycle using chrome.debugger API. I describe how to do that here- his application seems easily adaptable to your own. This is the only way to get the same caliber request manipulation capabilities in MV3 as in MV2.
Alternative approach:
-Use the chrome.webNavigation API. This will just entail setting up event listeners/handlers for one or more of the following:
onBeforeNavigate -> onCommitted -> [onDOMContentLoaded] -> onCompleted
Here you can find many examples of other projects using this API.
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
For a mobile web application I would like to emulate location movements of the device. While it is possible to override a single location using the Sensor Tab in Chrome's Developer Console (See: https://developers.google.com/web/tools/chrome-devtools/device-mode/device-input-and-sensors) I would like to override the location continuously, say for instance update the device's location every second.
Is there a possibility to achieve this in Chrome (or any other Desktop Browser)?
I am looking for a solution similar to the Android Emulator which allows to replay recorded GPS Tracks (From GPX or KML files):
(See: https://developer.android.com/guide/topics/location/strategies.html#MockData)
DevTools has no feature for this, but if you happen to be using getCurrentPosition() you can pretty much recreate this by overriding the function in a snippet.
I suppose this workflow won't work if you're using watchPosition() (which you probably are), because I believe that's basically a listener that gets fired when the browser updates the coordinates. There's no way to update the browser's coordinates.
However, I'll record the workflow below b/c it may be useful to somebody else.
Store your script in a snippet.
Override navigator.geolocation.getCurrentPosition() to the target coordinates.
So, you could store the coordinates and timestamps in JSON (either within the snippet, or just fetch the JSON from the snippet using XHR / Fetch), and then use setTimeout() to update the coordinates at the specified times.
var history = [
{
time: 1000,
coords: ...
},
{
time: 3000,
coords: ...
}
];
for (var i = 0; i < history.length; i++) {
setTimeout(function() {
navigator.geolocation.getCurrentPosition = function(success, failure) {
success({
coords: history[i].coords,
timestamp: Date.now()
});
}, history[i].time);
}
how can i disable the anti ddos throttling inside a chrome extension? it is currently only working by set the flag --disable-extensions-http-throttling
inside the extension shortcut, but this is not acceptable when the extension is running on many clients (i would need to set it manually on any client).
I have tried to disable it in the background.js script, but it is not working:
chrome.webRequest.onHeadersReceived.addListener(
function(info) {
var headers = info.responseHeaders;
var throttleHeader = {name: 'X-Chrome-Exponential-Throttling',
value: 'disable'};
headers.push(throttleHeader);
return {responseHeaders: headers};
},
{
urls: ['*://*/*'], // Pattern to match all http(s) pages
types: ['sub_frame', 'xmlhttprequest']
},
['blocking', 'responseHeaders']
);
Are there any other ways to disable throttling for a extension? I am using the latest version of chrome (50.0.2661.102 m)
There is most likely no way to disable throttling from within an extension. Allowing developers to do that would defeat the very purpose of throttling.
In fact the possibility to exploit the X-Chrome-Exponential-Throttling header for this purpose the way you just tried was considered a security issue:
https://bugs.chromium.org/p/chromium/issues/detail?id=318366
This eventually led to removing the X-Chrome-Exponential-Throttling header from Chrome in May 2015:
https://bugs.chromium.org/p/chromium/issues/detail?id=352259
This question already has answers here:
How to inspect contents of storage.local in Chrome Packaged App?
(2 answers)
Closed 8 years ago.
I am developing a chrome app that needs to save some data to the local storage and retrieve it afterwards.
I follow the guides on the Chrome storage API
https://developer.chrome.com/extensions/storage
and have a simple code to save data:
function saveCurrentPort()
{
chrome.storage.local.set({'last_port': connectedPortPath}, function() {
// Notify that we saved.
writeConsole('JS last port saved:' + connectedPortPath );
if (chrome.extension.lastError) {
alert('JS An error occurred: ' + chrome.extension.lastError.message);
}
});
}
After calling this with valid data, nothing gets saved in the local storage. Looking into the Resource tab in the developer tools window for my App I see no entry in the Local Storage section (nor in the Session Storage).
Of course, attempting to retrieve this data fails because the data isn't found.
This should be straight forward but simply doesn't work for me.
I run the App locally in developer mode.
Looking for other questions here I didn't see a case like this.
Any idea why it isn't working? am I missing something?
Thanks
Did you declare the "storage" permission to your manifest.json?
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
Plus, alert() is not allowed from chrome app.
I think there must be more errors. you might need to fix it first.
Besides permission you need to put the value of 'last_port'
var last_port_var= 'last_port';
var portObj= {};
portObj[last_port_var] = connectedPortPath;
Now set the value by object:
chrome.storage.local.set(portObj, function() {
//code goes here....
}
Hope this helps.