See what file/function deals with a WebSocket? - google-chrome

Is there a way to, possibly using the Chrome DevTools, see in what javascript file or function a WebSocket is handled with?
For instance, I am able to see the frames of the data in the Frames tab, but I am not able to find where they are handled. Is this even possible using only Chrome's DevTools?

I think doing a full-text search of the page source for "onmessage" is the easiest way of doing this.
Other than that, a more accurate method is to overwrite the native WebSocket object and putting in a debugger statement:
var nativeWebSocket = window.WebSocket
window.WebSocket = function(){
debugger
}
Paste this in the console before the WebSocket is created. You can use "Script First Statement" in Event Listener Breakpoints to pause when the page starts loading.
Chrome will pause when the WebSocket object is created, and you can go up the call stack to find the source code that's responsible.
This may be very different from where the onmessage handler is defined. However, you can then put a manual breakpoint on the line that contains new WebSocket, reload the page, and put this code in the console when the breakpoint is hit:
Object.defineProperty(e, "onmessage", {
set: function(){
debugger
}
})
Now the debugger will pause when the onmessage property is set on that WebSocket object.

Related

Chrome (open) Shadow DOM Events Not Reaching Host

I'm running Chrome 56.0.x (corporate mandate), along with Polymer 2. My sample component isn't doing anything fancy; just raising a CustomEvent after making a simple AJAX call. I'm setting "bubbles":true and "composed":true, and I can validate that the event is dispatched and that my host is listening for the event properly.
sample-component.html
raiseDataRetrievedEvent() {
this.dispatchEvent(
new CustomEvent('sample-component-data-retrieved', {
bubbles: true,
composed: true,
detail: { data: "loading complete" }
}));
}
However, the events never make it out of the Shadow DOM to my host page listeners.
index.html
// Listen to Custom event from Sample Component
document.querySelector('sample-component').addEventListener('sample-component-data-retrieved', function (e) {
alert(e.detail);
console.log(e.detail);
});
Interestingly enough, when I have a user initiated event (e.g. click) trigger this CustomEvent, it happily makes its way through the Shadow DOM to my listener. It's just the events that are programmatically created that are getting stuck.
UPDATE 1
This issue only seems to manifest itself when I'm serving my site locally (e.g. http://localhost, http://127.0.0.1, http://COMPUTERNAME). When I publish the site to another host, all the events seem to propagate as expected. Feels to me more like a Chrome issue at this point...
UPDATE 2
I put my code out on github here: https://github.com/davidfilkins/polymer-test.
I did some more testing and the results keep getting weirder... when I'm developing / testing in Chrome, I almost always have Dev Tools open. I noticed strangely enough that when my tools are open, that the event isn't captured by the host page (index.html)... but this seems to only happen locally. When I close tools and load the page locally, the events bubble properly... But this is only for the dispatched events that aren’t tied to an explicit user action; those all seem to work regardless of the tools being open or not.
When I access the simple Azure app that I created - http://samplepolymertwo.azurewebsites.net/index.html - all events are bubbled / captured regardless of whether the tools are open.
No clue if this is fixed in more current versions of Chrome or not.
The culprit was all timing...
In Chrome, with Dev Tools open, running on localhost, the event was dispatched from the component before the event listener was wired up on the host page.
Event Timing
I suppose the ideal scenario would be for the web component to wait until the event listener on the host had been wired up before broadcasting the event.

How to close browser popup in robot framework?

After login in Chrome browser, I am getting a save password popup from the browser. I want to handle that popup and want to close that using Robot Framework
Browse popup window
Thanks
This question has been asked and answered before with a pure Python context. This answer continues on this SO post for a working Robot Example.
The popup you see is generated by Chrome itself. It's not an HTML alert. For this reason none of the Selenium2Library keywords will have any effect on it. Nor wil settings cookies or javascript.
These settings can be manually set using the chrome://settings link. Go to advanced settings and then scroll down to Passwords and Forms. Untick the second item and this will prevent the popup.
To do the same automatically in Robot Framework the WebDriver needs to be started with additional preferences:
Chrome With Preferences
${chrome_options} = Evaluate sys.modules['selenium.webdriver'].ChromeOptions() sys, selenium.webdriver
${prefs} Create Dictionary credentials_enable_service=${false}
Call Method ${chrome_options} add_experimental_option prefs ${prefs}
Call Method ${chrome_options} add_argument --disable-infobars
Create WebDriver Chrome chrome_options=${chrome_options}
Go To https://secure.url.com
This key things here are credentials_enable_service=${false} where it is important to use ${false} and not false, as the latter is interpreted as a string and then added to Chrome as "false" instead of the correct value false.
The second item is that preferences are not added as arguments but through assigning a dictionary to the prefs property of the ChromeOptions() object like so: add_experimental_option prefs ${prefs}
I do not think this is real to be honest (as it's property of the browser.) Are you having issues with that? The only thing you can dismiss is javascript alert and probably the best way to handle this is:
${alert} = Get Alert Message dismiss=${dismiss}
I have this in my test teardown with Run Keyword and Ignore Error, it makes me able to fetch optional js alert content and debug (also dismisses it do the rest of the suite can be executed.)
Three Ways To do do it.
1) Many a times, Once pop-up appear on screen and Disappear a cookie is set which you can view in developer console-> application. If you set this cookie with value using Add Cookie keyword. Pop- up wont appear.
2) if first doesn't work, then open developer tools and monitor the local store from developer tools -> application and close the pop-up. U will notice some variable with a value is stored in local storage. You can set that value using your script and u wont see the pop-up while executing variable.
3) If first and second doesn't work, the pop-up is most likely linked to a javascript variable. set java script variable using Execute Javascript Keyword and your problem must be solved.
Talk with your dev team, to see which way will work for you.

chrome.runtime.connect from Content Script and DevTools Page JS failing to connect

I have reviewed this question/answer as well:
Communicating between Chrome DevTools and content script in extension
It looks like they are doing something slightly different than I am trying to do, so I don't know how much it applies. Maybe I absolutely need a background.js file?
I have also reviewed this question:
extension using background, content and devtools together
Here it looks like they are not using long-lived connections as documented here (which is what I need):
https://developer.chrome.com/extensions/messaging#connect
Anyway, previous question aside here is my problem:
I have tried this a few ways over the span of a few hours so I am pretty convinced I am just missing something here to make this work.
The crux of my issue is that:
chrome.runtime.onConnect.addListener(function(){...})
the listener here will never fire.
Here's my setup:
My extension uses a Content Script and a DevTools page. From both locations, the Content Script and DevTools page, I have tried to enabling messaging though chrome.runtime. My boilerplate initialization looks like this for starting the connection:
console.log('initializing connection');
var port = chrome.runtime.connect({name: 'My Extension'});
console.log('port', port.name);
and this for waiting for onConnect:
chrome.runtime.onConnect.addListener(function(port){
console.log('got connection!!!!!!');
});
My onConnect handler will never be invoked. I have tried placing the connection code (chrome.runtime.connect({...})) in the Content Script and in the DevTools page JS while placing the handler initialization the opposite location to no avail.
In other words, if I place the connection code in the Content Script, I will place the handler initialization into the DevTools page JS. If I place the connection code into the DevTools page JS I will place the handler initialization into the Content Script.
In both cases, I receive no runtime errors, however, I also never see the console.log('got connection!!!!!!'); get called. Yes, I am looking at the DevTools page console when I have the handler initialization located in the DevTools page JS.
I simply must just be misunderstanding something or missing something in the docs. Can anyone point me in the right direction re: having DevTools Page JS communicate with a Content Script?
As per Xan comment, communication between devtools extension and content scripts should be done through the use of a background script. The process is basically:
(devtools script) - create the connection ( and sends or listens to messages through the connection port opened)
(background script) - listen for the connection to be created, receiving the port and using it to listen or broadcast messages
This is useful if you want to keep a long lived connection, so basically you will need a couple of messages to be passed back and forward for a single process. If you want simple messages to be passed from time to time, but don't need multiple messages being passed back and forth then you might implement a more simple communication:
(devtools script) - sends a message using the chrome.runtime.sendMessage
(background script) - listens for messages send by any extension associated with it using the chrome.runtime.onMessage.addListener()

How to get appWindow from Chrome.app.window.create

I am trying to write a chrome.app that is able to open and close chrome.app windows on both displays of a system that is configured with two monitors. When launched, the chrome application establishes a socket connection with a native application running on the same computer, I also open a hidden window via chrome.app.window.create to keep the chrome application up and running. The native application then reads a configuration file and then sends a series of ‘openBrowser’ commands to the chrome application via the socket.
When the chrome application receives an ‘openBrowser’ command, the chrome application makes a call to the chrome API method chrome.app.window.create, passing the create parameters AND a callback function. A code snippet is below:
NPMBrowserManager.prototype.openBrowser = function (browserId,htmlFile,browserBounds,hidden,grabFocus)
{
var browserManager = this;
var createParameters = {};
createParameters.bounds = browserBounds;
createParameters.hidden = hidden;
chrome.app.window.create(htmlFile,createParameters,function(appWindow)
{
// Check to see if I got a non-undefined appWindow.
if(appWindow !== null)
{
browserManager.browsers.push({"browserId":browserId,"window":appWindow});
console.info("NPMBrowserManager.openBrowser: Added browser, id =" + browserId + ", count =" + browserManager.browsers.length);
}
});
}
Unfortunately, the ‘appWindow’, parameter passed in the create callback is always undefined. I suspect it has something to do with the fact that the method openBrowser is itself being called by another method that processes commands received from the native application. However, the window opens exactly here and when I want to to, I just can’t seem to cache away any information about the new window that can be used later to close or move the window.
I want to be able to cache away the appWindow so that I can close or modify the created window later on in the workflow.
As a side note, I’ve noticed that appWindow is NOT undefined if I call the openBrowser method from within the callback that is associated with the chrome.app.runtime.onLaunched event. I suspect it has something to do with the current script context. I was not able to find any chrome.app documentation that goes into any detail about the chrome app architecture.
I would GREATLY appreciate it if anyone out there can explain to me how I can get the appWindow of the window that is created in the chrome.app.window.create method. By the way, I have also tried calling chrome.app.window.current to no avail… Very frustrating!!!
I’d also be interested in any documentation that might exist. I am aware of developer.chrome.com, but could not find much documentation other than reference documentation.
Thanks for the help!
Jim

Access-Control-Allow-Origin error in a chrome extension

I have a chrome extension which monitors the browser in a special way, sending some data to a web-server. In the current configuration this is the localhost. So the content script contains a code like this:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(data)...
xhr.open('GET', url, true);
xhr.send();
where url parameter is 'http://localhost/ctrl?params' (or http://127.0.0.1/ctrl?params - it doesn't matter).
Manifest-file contains all necessary permissions for cross-site requests.
The extension works fine on most sites, but on one site I get the error:
XMLHttpRequest cannot load http://localhost/ctrl?params. Origin http://www.thissite.com is not allowed by Access-Control-Allow-Origin.
I've tried several permissions which are proposed here (*://*/*, http://*/*, and <all_urls>), but no one helped to solve the problem.
So, the question is what can be wrong with this specific site (apparently there may be another sites with similar misbehaviour, and I'd like to know the nature of this), and how to fix the error?
(tl;dr: see two possible workarounds at the end of the answer)
This is the series of events that happens, which leads to the behavior that you see:
http://www.wix.com/ begins to load
It has a <script> tag that asynchronously loads the Facebook Connect script:
(function() {
var e = document.createElement('script');
e.type = 'text/javascript';
e.src = document.location.protocol +
'//connect.facebook.net/en_US/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
Once the HTML (but not resources, including the Facebook Connect script) of the wix.com page loads, the DOMContentLoaded event fires. Since your content script uses "run_at" : "document_end", it gets injected and run at this time.
Your content script runs the following code (as best as I can tell, it wants to do the bulk of its work after the load event fires):
window.onload = function() {
// code that eventually does the cross-origin XMLHttpRequest
};
The Facebook Connect script loads, and it has its own load event handler, which it adds with this snippet:
(function() {
var oldonload=window.onload;
window.onload=function(){
// Run new onload code
if(oldonload) {
if(typeof oldonload=='string') {
eval(oldonload);
} else {
oldonload();
}
}
};
})();
(this is the first key part) Since your script set the onload property, oldonload is your script's load handler.
Eventually, all resources are loaded, and the load event handler fires.
Facebook Connect's load handler is run, which run its own code, and then invokes oldonload. (this is the second key part) Since the page is invoking your load handler, it's not running it in your script's isolated world, but in the page's "main world". Only the script's isolated world has cross-origin XMLHttpRequest access, so the request fails.
To see a simplified test case of this, see this page (which mimics http://www.wix.com), which loads this script (which mimics Facebook Connect). I've also put up simplified versions of the content script and extension manifest.
The fact that your load handler ends up running in the "main world" is most likely a manifestation of Chrome bug 87520 (the bug has security implications, so you might not be able to see it).
There are two ways to work around this:
Instead of using "run_at" : "document_end" and a load event handler, you can use the default running time (document_idle, after the document loads) and just have your code run inline.
Instead of adding your load event handler by setting the window.onload property, use window.addEventListener('load', func). That way your event handler will not be visible to the Facebook Connect, so it'll get run in the content script's isolated world.
The access control origin issue you're seeing is likely manifest in the headers for the response (out of your control), rather than the request (under your control).
Access-Control-Allow-Origin is a policy for CORS, set in the header. Using PHP, for example, you use a set of headers like the following to enable CORS:
header('Access-Control-Allow-Origin: http://blah.com');
header('Access-Control-Allow-Credentials: true' );
header('Access-Control-Allow-Headers: Content-Type, Content-Disposition, attachment');
If sounds like that if the server is setting a specific origin in this header, then your Chrome extension is following the directive to allow cross-domain (POST?) requests from only that domain.