Polymer testing: too much recursion? - polymer

I am currently testing a polymer element and need to wait for a variable to be set in my element. After searching how to instruct Javascript to wait for the variable to be set, I came up with the following code:
var behavior;
setup(function(){
behavior = fixture("behavior");
});
test('Behavior loads resources', function(done) {
var waitForI18n = function() {
if(behavior.isI18nLoaded){
clearInterval(interval);
expect(behavior.getKey("test")).to.be.equal("test" + behavior.language.toUpperCase());
done();
}
};
var interval = setInterval(waitForI18n, 50);
});
This works in Chrome but other browsers just freeze and eventually crash: IE11, Edge, Firefox.
I was able to get a "Too much recursion" error in firefox, but not much else.
Am I doing anything wrong? Any ideas?
I've tried with a recursive setTimeout, but the behavior was the same: Chrome works, but not other browsers.

Related

Detect if another browser tab is using speechRecognition

Is it possible to tell if another Chrome tab is using webkitSpeechRecognition?
If you try to use webkitSpeechRecognition while another tab is using it, it will throw an error "aborted" without any message. I want to be able to know if webkitSpeechRecognition is open in another tab, and if so, throw a better error that could notify the user.
Unless your customer is on the same website(you could check by logging the ip/browserprint in database and requesting by json) you cannot do that.
Cross domain protection is in effect, and that lets you know zilch about what happens in other tabs or frames.
I am using webkitSpeechRecognition for chrome ( does not work on FF) and I faced same issues like multiple Chrome tabs. Until the browser implement a better error message a temporary solutions that work for me:
You need to detect when a tab is focused or not in Chrome using
Javascript.
Make javascript code like this
isChromium = window.chrome;
if(isChromium)
{
if (window.addEventListener)
{
// bind focus event
window.addEventListener("focus", function (event)
{
console.log("Browser tab focus..");
recognition.stop();// to avoid error
recognition.start();
}, false);
window.addEventListener("blur", function (event)
{
console.log("Browser tab blur..");
recognition.stop();
}, false);
}
}
There's a small workaround for it. You can store the timestamp in a variable upon activating SpeechRecognition and when it exits after a few seconds of inactivity, it will be compared to a timestamp since the SpeechRecognition was activated. Since two tabs are using the API simultaneously, it will exit immediately.
For Chrome, you can use the code below and modify it base on your needs. Firefox doesn't support this yet at the moment.
var transcriptionStartTime;
var timeSinceLastStart;
function configureRecognition(){
var webkitSpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition;
if ('webkitSpeechRecognition' in window) {
recognition = new webkitSpeechRecognition();
recognition.continuous = true;
recognition.interimResults = true;
recognition.lang = "en-US";
recognition.onend = function() {
timeSinceLastStart = new Date().getTime() - transcriptionStartTime;
if (timeSinceLastStart < 100) {
alert('Speech recognition failed to start. Please close the tab that is currently using it.');
}
}
}
}
See browser compatibility here: https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition

Chrome extension: (DOM)Debugger API does not work anymore

Our chrome extension does not work correctly anymore since version 37.0.2062.103 (It used to work correctly on chrome version 36.0.1985.143).
Specifically, the debugger API has stopped working for us when we use the DOMDebugger.
See the attached code: (background.js)
chrome.tabs.onUpdated.addListener(function(tabId,changeInfo,tab){
if( changeInfo.status == "loading" && tab.active){
var debugId = {tabId:tabId};
chrome.debugger.attach(debugId, '1.0', function() {
chrome.debugger.sendCommand(debugId, 'Debugger.enable', {}, function() {
chrome.debugger.sendCommand(debugId, "DOMDebugger.setEventListenerBreakpoint", {'eventName':'click'},
function(result) {
console.log('registering click');
});
});
});
}
});
chrome.debugger.onEvent.addListener(onEvent);
function onEvent(debuggeeId, method,params) {
if(method=="Debugger.paused"){
console.log('DONE!');
}
};
The extension successfully starts the debugger. we get the yellow debugger ribbon.
We also see the 'registering click' msg in the console. the result argument is an empty object {} (line 8).
However upon clicking on a button that has a click event listener nothing happens.
It used to work without any issues.
It seems like it regressed with https://codereview.chromium.org/305753005. One needs to call "DOM.enable" for it to work now. On the Chrome side, we should implicitly enable DOM domain upon setEventListenerBreakpoint for backwards compatibility. Unfortunately it already squeezed into the stable release.

IndexedDB not working in FireFox and IE

I have the latest versions of Firefox and IE, but the example in html5rocks.com is not working in these two browsers. I tested with Chrome and it works fine.
I have noted that these browsers does not fire any event ('onsuccess' or 'onerror') on attempting to open the indexedDB as follows.
var request = indexedDB.open("todos");
Please share any ideas/solution for this issue.
to make html5rocks demo work on Firefox you need to attach onupgradeneeded event on database open instead of setversion method for creating the database.
here is the code sample that works both on Firefox and Chrome:
myStorage.indexedDB.open = function() {
var v = 1;
var request = indexedDB.open("todos", v);
//Firefox code for db init
request.onupgradeneeded = function (e) {
myStorage.indexedDB.db = e.target.result;
var db = myStorage.indexedDB.db;
// We can only create Object stores in a setVersion transaction;
if(db.objectStoreNames.contains("todo")) {
var storeReq = db.deleteObjectStore("todo");
}
var store = db.createObjectStore("todo",
{keyPath: "timeStamp"});
}
request.onsuccess = function(e) {
myStorage.indexedDB.db = e.target.result;
var db = myStorage.indexedDB.db;
//Chrome code for db init
if (v!= db.version && db.setVersion) {
var setVrequest = db.setVersion(v);
// onsuccess is the only place we can create Object Stores
setVrequest.onerror = myStorage.indexedDB.onerror;
setVrequest.onsuccess = function(e) {
if(db.objectStoreNames.contains("todo")) {
db.deleteObjectStore("todo");
}
var store = db.createObjectStore("todo",
{keyPath: "timeStamp"});
myStorage.indexedDB.getAllTodoItems();
};
}
else
myStorage.indexedDB.getAllTodoItems();
};
request.onerror = myStorage.indexedDB.onerror;
}
Edit: Here is a link to working version of the html5roks ToDo demo, which I maintain on github, expanded with two new features for viewing details data and updating values.
Chrome is behind on the IndexedDB standard.
There was a new revision introduced in December and Firefox and IE have upgraded. Chrome has not yet.
I believe it's mostly folks from the Chrome crew who run HTML5Rocks.com so it makes sense why these examples would be behind.
The big change between the pre and post-December 2010 API are the change in setVersion requests and the new onupgradeneeded callback.
Todo list example is outdated IndexedDB specification implemented on chrome. Now you got to use onupgardedneeded method, and well setVersion too for now.
IndexedDB is not supported on IE. Visit html5test.com for verification
Edit 2015: IndexedDB API is available in IE as of version 10

How to investigate webScoket failures on Safari?

I just started learning WebSockets today. I am using Safari and the following C# as my WebSocket server (http://www.codeproject.com/KB/webservices/c_sharp_web_socket_server.aspx).
My client is as simple as the following:
<script type="text/javascript">
try{
var socket = new WebSocket('ws://localhost:8181');
alert(socket.readyState);
socket.onopen = function() {
alert('opened...');
};
socket.onclose = function() {
alert('closed');
};
socket.onerror = function(){
alert('error!');
}; }
catch(exception){
alert(exception);
}
</script>
On Safari, am getting the message "Closed" which means the event onclose was raised before the onopen(). I suspecting that the server is closing the connection, any idea? Also, what's the best way to investigate issues like this? any error or reason code?
Thanks!
I guess I figured it out. On Safari you can enable Developer Tools and I was getting missing Sec-WebSocket-Origin header so I went ahead and changed the following:
WebSocket-Origin changed to Sec-WebSocket-Origin

Replacing page functions via userscript in Chrome?

I've created a Greasemonkey script which replaces a page function:
(function() {
var oldFunc = func;
func = function() {
oldFunc();
// other stuff
};
)();
I had always intended this script to work in both Gresemonkey and Chrome and had read that Chrome doesn't support unsafeWindow, so have been injecting the script into the page by converting the function to a string and using setTimeout:
setTimeout("(function(){var old=func;func=function(){old();/*other stuff*/}}())", 0);
This works perfectly well in Greasemonkey, but gives me absolutely nothing in Chrome. It clearly isn't firing, but nothing appears in the log, either. I have tried a number of other injection styles, but can't get anything to work. (For testing, I also added an alert() to the top of the function.)
setTimeout(..., 0) — nothing
Running the function in-scope, without injection into the page — no alert, but "func is not defined" in console
document.href = "javascript:..." — nothing
document.body.addEventListener("load", ...) — nothing
All of these are with #run-at document-end.
Unfortunately, this being my first Chrome userscript, I'm at a loss as to how to debug it, even after an hour or so of Googling and poking around SO. Any help?
Actual script, currently working in Greasemonkey: http://pastebin.com/HtLVjYHg
In the end, the only technique I found which worked in Chrome was to create a <script> node using DOM methods. Fortunately, this seems to work equally well in Firefox and Opera and is made fairly painless by <func>.toString():
function embed() {
var oldFunc = window.func;
window.func = function() {
oldFunc();
// other stuff
};
}
var inject = document.createElement("script");
inject.setAttribute("type", "text/javascript");
inject.appendChild(document.createTextNode("(" + embed + ")()"));
document.body.appendChild(inject);
Final script: http://userscripts.org/scripts/review/84394