how user agent in network conditions tab works - google-chrome

This is the screenshot of network conditions tab in google chrome. It allows you to set browser specs.
I am wondering, how is this done? It surely doesn't change navigator object directly, since it is read-only.

It uses the setUserAgentOverride method of the debugging protocol. Chrome then handles that value internally.

Related

How to set the page settings with puppeteer?

When performing some actions, chrome sometimes requires the user's permission. How can I accept these popups with puppeteer (In my case "Download multiple files")?
I'm afraid that this is currently not-supported and doesn't appear to be in the near future. According to this ticket, it's apparently not an easy task that's going to be taken on soon.
You might look into using xvbf on "headful" Chrome as opposed to using headless as that appears to be the flag that causes Chrome to not use user-settings.

How do I get password fields to be autofilled without requiring user interaction?

If I inspect an <input type="password"/> from my Tampermonkey script and observe changes using a change handler for a password field that is filled by the Password Manager feature of Chrome, the value remains empty until I physically perform a real click in the page. I have tried in my script clicking in the page, but Chrome knows it’s not a real click. When I physically click in the page, the change event suddenly fires, the password field gets a value, and then my script reacts properly (due to having the change event). But I wrote this script to avoid having to interact with the page in the first place, so this defeats the point of my script.
Is there a way to get TamperMonkey to mark the page as having had the user interact with it (e.g., some hypothetical GM_setUserTouched() or GM_autoFillPasswords() API) so that the Password Manager feature actually fills the <input type="password"/> in without requiring me to click in the page?
Background
In Chrome, this behavior is documented in #352527 comment 15 where it is unexpected behavior to the reporter and #398805 where there is a case that Chrome fails to implement the behavior I don’t want. It is considered a feature that when autofill and Chrome’s built-in Password Manager fill out a form, password characters are displayed to the user in the password field, but the DOM HTMLInputElement.value is set to "". When the user interacts with the page, such as by clicking in it or pressing a key, Chrome modifies HTMLInputElement.value to contain the password and a change event is fired at the element. The cited reason for doing this is “security reasons” (e.g., if a website script was reading from the password element, it only would have a chance to do so if the user was looking at the page… so popunders or non-visible frames wouldn’t be able to do it or something? I’m not sure what this protects you from: once the user interacts with the page, all of the scripts would have access to the password anyway. And if bad scripts are being served from the same origin as the <input type="password"/>, the website itself has a security flaw, not Chrome…).
Greasemonkey historically has helper APIs and a #grant system to enable the userscript to work around issues like this. Edit: when creating the repro (below), I discovered that Firefox makes the autofill password available to the DOM without waiting for the user to interact with the window. Thus, Greasemonkey doesn’t need a GM_forceAutofill() API because Firefox doesn’t exhibit this Chrome quirk. As a result, Tampermonkey doesn’t have such an API.
Repro
Because people do not believe me when I describe the behavior exhibited by Chrome, I have prepared a repro. It takes some work to get Chrome into a state where it doesn’t think the user has interacted with the page yet, but you should be able to see what I see using these steps:
Open Chrome. I am using Chrome 61.0.3163.91 64-bit on Windows 10.
Navigate to https://fiddle.jshell.net/xqfynp3e/22/show/light/
Enter some bogus username and password and hit enter or click the button. Chrome should prompt you to save the password.
Save the password.
Open Developer tools.
Enter this into Console (to navigate to the page without accidentally interacting with it): window.location.href = 'https://fiddle.jshell.net/xqfynp3e/22/show/light/?1'
Run document.querySelector('input[type=password]').value in Console.
Observe that the form’s password appears to be filled in visually and yet reading the DOM element in Console yields "".
Click in the document.
Run document.querySelector('input[type=password]').value in Console again.
Observe that the form’s password hasn’t changed appearance and yet reading the DOM element in Console yields the bogus password you saved.
My question, restated: how can I get Tampermonkey to perform the “Click in the document” step? How do I tell Chrome’s password auto-filler that I interacted with the page without actually physically interacting with the page?
EDIT: I have found an alternative way to securely store passwords in Chrome and access them via userscripts by using the Credentials Web API’s silent mediation support: https://imgur.com/a/ts2W1
You cannot do this using Google's built-in password storage because, as you stated yourself, Chrome requires user interaction to enable such passwords -- as a security feature.
Specifically, Chrome requires an event with the isTrusted property set to true. Tampermonkey cannot work around this because even Chrome extensions are not able to set the isTrusted property.
See also, this related feature request from 2015.
One solution is to use a password manager that fills these fields without using Google's built-in storage.
There are many available, with varying degrees of cross-device, and cross-browser, support.
Or you can write your own Tampermonkey script to fill in these fields, irregardless of what Chrome has stored.
If you do write a Tampermonkey script, I recommend that you use a secure storage framework, don't hardcode login info into the script.

Logging network tab automatically without opening it in Google Chrome

I need to log the information shown in network tab to a file. I can do it by firing network tab first and then exporting it to a file. But is it possible to run the network tab and exporting it to a file in the background automatically whenever the Chrome is opened?
Is it possible to do?
It depends on your requirement. If your extension involves DevTools, and therefore it is open, you can use the chrome.devtools.network.getHAR() method to get the network traffic. You don't need to navigate to the Network tab.
However, if you want to access the network data without DevTools being opened, this API will not work, as it's only exposed to the DevTools instance. There are a couple of possible options.
Option 1
You could use the chrome.webRequest API to intercept each request/response and append whatever data you want/can to an object. You could then use the chrome.downloads API to download the data. In your case, you could use a data URI.
var url = 'data:application/json;base64,' + btoa(data);
chrome.downloads.download({url: url, filename: 'notQuiteAHAR'json'});
I haven't tested this in practice, and I'm not too sure if you can determine when all requests are done before calling the download.
Option 2
Use the more low level chrome.debugger API, as per the comment by #wOxxOm. The debugging protocol only allows one instance of the debugger at a time, so this will only ever work if you don't have DevTools running. The API exposes a lot more than the chrome.webRequest API, but requires a bit of work to get all the data you need.
There's a repository called chrome-har-capturer, which uses the debugging protocol. Of particular interest is har.js, which uses the events found in the debugger API to manually construct the HAR. The purpose of the library is for remote debugging purposes, but I believe you can use the debugger API in an extension, and so you could probably use aspects of this repository.
As suggested by Gideon Pyzer, HAR Recorder uses chrome debug protocol to record HAR and generate a har file (without opening devtools). If you want a variation, you can fork and make changes on it.

How to delay script/asset loading in Chrome Developer Tools

Is there any way to add a time delay to a script/asset loading in the Google Chrome Browser via the Chrome Developer Tools? Or to block a script loading entirely?
The reason I want to do this is to see how a site performs when a script/asset suffers from delayed loading or failed loading.
In Chrome Developer Tools when you are in the Network you can add custom throttling. You can specify download and upload speed as well as request latency. But this will apply to all resources and not only to a specific one.
--- edit ---
For delay individual URLs on any page, you can use a chrome extension (since it can intercept browser requests). I use https://chrome.google.com/webstore/detail/url-throttler/kpkeghonflnkockcnaegmphgdldfnden
If the asset is a third party or hosted on a different domain, there is a Chrome plugin that's designed to test what you are calling loading delays, that are also called SPOF (Single Point Of Failure). It might not be very intuitive at first use, but it's very helpful :
The plugin is called SPOF-O-Matic and can be found here: https://chrome.google.com/webstore/detail/spof-o-matic/plikhggfbplemddobondkeogomgoodeg
Following solutions have nothing with Chrome Devtools but they work.
If you don't mind redirects then you can try Slowwly or deelay.me.
Other alternative for non-windows OS is Comcast.
You can do it by combining multiple resources.
I use http://www.deelay.me/ to generate the delayed url.
I then combine it with requestly extension (https://requestly.io/) to create a host replace rule to target a specific resource
This devtools extension can fit your requirement, Its a Chrome/Firefox devtools extension that can simulate http request delay for any configurable URL.
Chrome devtools extension webstore
You can use Requestly Browser Extension or Desktop App to modify your network requests. Delaying/Throttling scripts is one of the use-cases amongst many already supported in Requestly.
Here's how you can do it. Once you install Requestly, Use the Delay Request feature.
Create New Rule & Select Delay Rule Type
Define URL (or URL Pattern) and the delay value
This article explains 3 different approaches to add delay/throttle APIs (or network requests). However, in your case Requestly extension based approach should work best.
PS - I built Requestly.

Can a server differentiate between the Chrome Webdriver and actual Chrome?

As far as I can tell, there's no way for a server to tell whether it's being accessed through the Chrome Webdriver or by an actual user in front of Chrome. Is this correct?
Without specific checks on the server side I doubt that it can be detected.
However, it can be put in place. One way that I'm thinking of is checking the browser preferences.
Let's take for instance the new Selenium driver used for Firefox versions 48+, the Marionette-based geckodriver. Mozilla took ownership of the driver server and citing from the Github project page:
Proxy for using W3C WebDriver-compatible clients to interact with
Gecko-based browsers.
This program provides the HTTP API described by the WebDriver protocol
to communicate with Gecko browsers, such as Firefox. It translates
calls into the Marionette automation protocol by acting as a proxy
between the local- and remote ends.
To achieve this, Mozilla implemented some WebDriver extensions built in into the browser itself.
If you go to about:config in Firefox and search for webdriver you will see some preferences that, when the browser is started by the Selenium driver they appear as user set. So this is one way of checking it.
Another one, somehow related to the first one is the Firefox profile that Selenium WebDriver creates when starts the browser that has a kind of distinguishable name. One note although, this is only using the default Selenium settings. If you, as a user create a Firefox profile that afterwards get imported in the Selenium WebDriver before initialization, there won't be any more difference, except the first point mentioned. The user preference settings.
And in same manner, this applies to all the Selenium browser drivers, so it would be applicable to Chrome to some extent too. However, I'm sorry that I can't be more specific like in Firefox's case.