Firefox optimization bug? - javascript

Recently when i did some adventofcode, i came across a bug:
The bug happens in firefox except for if you run the code as multiple chunks, but doesnt happen in chrome.
When i run this code in the firefox console, in a tab with url https://www.google.com/robots.txt :
// Fetch input
var input = await fetch("https://www.google.com/robots.txt").then(r => r.text());
var lines = input.split("\n");
// Iterate
while(lines.length > 0) console.log(lines.shift());
It prints nothing, but when i run the code as two pieces (separated by // Iterate) it works. Note that you can change the fetch url and url of the tab, i chose robots.txt and made them the same to avoid CORS errors.
Does anyone know why this happens or how to fix this?
Edit: The code works if you wrap the code in an async function and call it, but it should work regardless.

Related

Thunderbird ADDON: port.postmessage() does not work reliably

I am trying, and trying, and trying , … to debug an addon that I wrote for Thunderbird 78.10.2. It sends message to a python backend and then reads the reply back:
async function buttonListener(tab) {
tabId = tab.id;
port = browser.runtime.connectNative("backendMyEd");
cD = await browser.compose.getComposeDetails(tab.id);
var body = extractBody(cD);
await port.postMessage(body);
port.onMessage.addListener(getReply);
}
The listener is just a python script that is doing:
def get_message():
if sys.version_info < (3, 0):
len_field = sys.stdin.read(4)
else:
len_field = sys.stdin.buffer.read(4)
if not len_field:
sys.exit(0)
message_length = struct.unpack('=I', len_field)[0]
message = sys.stdin.read(message_length) <=====
return json.loads(message)
This works half the time but not always. When it doesn’t, my printfs tell me that it’s stuck in stdin read, but port.postMessage() has returned. If I quit TB or remove my add on, the sys.stdin.read() finishes.
Several things come to mind:
Is there a flush needed after port.postMessage()? maybe its not flushing all the time?
could it be related to message size? i tested with different sizes, and for less than 8k it often works. For larger ones, it seems to not work more often.
Could there be some special characters in message causing this?
Something to do with JS being single threaded? But the function is async, and python should be a different process. I also tried doing a fork in python, still hangs off and on in sys.stdin.read()...
Any ideas on whats going on, or how I could debug further?

Filter Link Tracking issue in Adobe DTM

I am facing issue with adobe image request in network tab, I can proper see results in console, but while in image request I am not seeing Evar55 current value.
Actually there is bug Analytics tracking issue- Evar55
Evar55 should capture the value of filter selected by users on search result page and PLP.
So now the next thing I have written the code, which is working absolutely fine in Console, and I can see the result but in network tab the image request is giving previous value not giving the current value of facet.
Here I am sharing the screenshot and code with you, please tell what issue is.
In DTM, I have created page load rule – conditions trigger rule at DOM ready –then adobe analytics open editor I have pasted this code
Code
var oldXHR = window.XMLHttpRequest;
function newXHR() {
var realXHR = new oldXHR();
realXHR.addEventListener("readystatechange", function() {
if(realXHR.readyState==4 && realXHR.status==200){
//run your code here
window.setTimeout(function() {
if(s.pageName && (s.pageName.indexOf('plp:')>-1 || s.pageName.indexOf('search')>-1)){
var PFF = document.getElementsByClassName('selected-categories')[0].innerText;
PFF_Final = PFF.replace(/ /g, '').replace(/:/g, '|');
if(PFF_Final.indexOf('Categories|')>-1 || PFF_Final.indexOf('search|')>-1){
console.log('N/A');
}
else if(PFF_Final && typeof PFF_Final !== 'undefined' && PFF !== 'null' && PFF !== ''){
//PFF_Final = PFF.replace(/ /g, '').replace(/:/g, '|');
s.linkTrackVars = 'eVar91';
s.eVar91 = PFF_Final.trim();
//s.tl(this, 'o');
console.log(PFF_Final);
}
}
},1500);
}
}, false);
return realXHR;
}
window.XMLHttpRequest = newXHR;
Note : - I have change the Evar55 to Evar91 because Evar 55 which is already in use.
enter image description here
enter image description here
Thanks,
Payal
At face value, the immediate reason the code you posted does not make a request because you have the s.tl call commented out...
Second, a note: if you are filtering for image requests in the network tab, you will almost certainly not see the Adobe Analytics (AA) request there, because unless you are using a very ancient browser or else have javascript turned off and using the <img> tag method, it will show up as either a javascript request or ajax (xhr) request (depending on what version of the AA library and how long the request is).
If you are still not seeing the request, there are a couple additional things to try. One or more of these may or may not be true/necessary, depending on what version of the AA library you are using:
1) When you pass this as the first argument, it must be a valid anchor element with an href attribute <a href='..'></a>. Since this is not applicable within the context of your posted code, try changing the first argument to boolean true.
2) Add a 3rd argument to the s.tl call. This argument is supposed to be a description for the link click, e.g. s.tl(true,'o','some link'); It can be anything you want; it's what shows up in the native link reports in AA (that you will almost certainly ignore, in favor of looking at that eVar91 report, instead). All versions of the AA library require this 3rd argument if you want to track it as a click/interaction server call. Without it, in more recent versions of AA, it will trigger the request as a page view call, but in older versions of the AA library, it will not trigger a call at all.
3) Again, depending on your AA lib version, it will not include anything above eVar75. I don't remember the exact AA version where eVar76+ was introduced (edit: Looks like Starting AM1.4. Legacy H code not supported). As a quick check, try using eVar75 or lower to see if it shows up in the request. Note: I'm only putting this for completeness sake, but I don't think this your issue, since it seems from your post you may have tried with eVar55 already? But may as well be certain. If this is the case, I would suggest updating to the latest AppMeasurement library. If for some reason you are unable to do that, and still need to use eVar91, then the alternative is to pop it as a contextData variable, e.g. s.contextData['eVar91']='foo'; and then map it to the real eVar91 in a Processing Rule within the AA interface. If your AA library is old enough that even contextData variables don't work (H23.2 or lower).. then I suggest you make it your highest priority in life to upgrade to a more recent version of the AA lib..
If after all of this you still do not see an AA call, just type s.t(true,'o','foo'); into the js console. Do you see an http request? If you do not see a request, then you have some deeper issue not directly related to the posted code. Perhaps your AA library is not present, or it is not loaded before this is triggered, or is under a different namespace than the default s namespace. But it's not really feasible to write lots of random guesses here vs. looking at the site.
If you do see a request, then my best guess at this point is you having a timing issue. Perhaps there is a page (re)load happening and it is not getting a chance to trigger? But again, it's not very feasible to speculate on a site unseen.

How do we correctly click on a link or button using Javascript?

I'm using the PHP + Ajax version of this template: http://192.241.236.31/themes/preview/smartadmin/1.5/ajaxversion/, Codeception WebDriver (Selenium) to perform my tests. Most of them are working fine, but I have some random, yes, random!, failing tests, so I always get back to them and try to harden, hoping it will not randomly fail sometime in the future. One of the failing reasons are usually due to wrong clicks on the interface. I tell Codeception to click the #element-id and when it fails, I see that it actually had a different page showing in the output png, but the link activated showing it tried to click the correct link. Sometimes I just have to load a different page before clicking that particular link and wait 10 seconds for it to render, and it works, silly huh? Yeah, but sometimes this doesn't work either.
This is how I used to test things:
$I->click('#element-id');
And I have to use the element id, because it's a multi-language app, all (mostly) strings come from a strings file and they might change at some point and break tests.
After too many random tests failing, I decided to make the frontend itself responsible for clicking things during tests, it's a long and silly circunventing shot, but it should be work, so I created a functionalHelper:
public function clickElement($element)
{
$I = $this->getDriver();
$I->executeJS("clickElement('{$element}');");
}
And two Javascript functions:
function clickElement(element)
{
element = jQuery(element);
if(typeof element !== undefined)
{
fakeClick(element[0]);
}
return true;
}
function fakeClick(object)
{
if (object.click)
{
object.click();
}
else if(document.createEvent)
{
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
var allowDefault = object.dispatchEvent(evt);
}
}
I'm using jQuery in the first one because it's already available in the template and it's easier to select non-id'ed things.
This is working fine, and you can test it yourself by
1) Opening the page:
http://192.241.236.31/themes/preview/smartadmin/1.5/ajaxversion/
2) Loading the script in your browser console by executing
loadScript('https://www.dropbox.com/s/kuh22fjjsa8zq0i/app.js?dl=1');
3) And clicking things:
Calendar
clickElement($x('//*[#id="left-panel"]/nav/ul/li[7]/a/span'));
Widgets
clickElement($x('//*[#id="left-panel"]/nav/ul/li[8]/a/span'));
Because the template is using the hash character to control the ajax part of the page and not reload everything, I had to (programatically) add the referer-url to all my href links, so I could, in my app, redirect back to the referer, as the hash part uf the accessed url is not sent to the server. This is a link example:
<a href="/users?referer-href-url=/dashboard" title="Users" id="users-navigation">
<span class="menu-item-parent">Users</span>
</a>
Wich basically means the user was looking at the dashboard when she clicked the users link. If something wrong happens, the app will redirect the user back to the dashboard, with an error message.
The problem is that, somehow, during tests, the current url, when tested using:
$I->seeCurrentUrlEquals('/#/clients?referer-href-url=/clients');
Becomes
/#/clients
Instead of
/#/clients?referer-href-url=/clients
This happens sometimes, because some other it also works. If I browse the site manually it works in 100% of the time and I always see the correct URL in the address bar. And if I manually execute clickElement() it also works fine. The problem only heppens my my suite is running.
Here's an example of it passing (green):
And the exact same test randomly failing (red):
This is the code related to the failing test:
$I->clickElement('#clients-navigation');
$I->waitForText('Jane Doe', 10);
$I->seeCurrentUrlEquals('/#/clients?referer-href-url=/clients');
I usually wait for something after a click, so the page can have time to render.
You can also see that there are a lot of "I click element", using those PHP and Javascript functions without a problem.
I'm using:
Ubuntu 14.04
PHP 5.5.9
Codeception 2.0.7
Selenium 2.44.0
Firefox 33.0
So, what could be the problem here?
Is this the correct way to click an element in Javascript?
In the process I also experience tests which does not fail when ran singly and fails when in batch, but this might be a different question, right?

Push error while using javascript & PHP

I did try to find solution by myself and tried to fix it but without any good result. I assume it's probably something easy to fix but I got confused and decided it will be better to ask some more advanced people.
I am trying to do some small easy clicking game using javascript (+YUI library, JSON) and everything was fine the code was working, everything is ok as far as I was just using it as .html and simply opening the index.html by my browser (code in code.js and then index.html calling the script) but then I tried to upgrade it and make it to PHP and still everything looks alright till the momment when I launch my "website" by xampp and go to it by localhost, everything looks good and most of the code/website is working but by some reason one main function instead of working is giving me huge amount of text (It was not showing me everything, but this is what Firebug gave me):
<p id="add">function (a){this.push.apply(this,a);return this;}function (d){if(this.length<3){return null;}if(this.length==4&&this[3]==0&&!d){return"transparent"; }var b=[];for(var a=0;a<3;a++){var c=(this[a]-0).toString(16);b.push((c.length==1)?"0"+c:c);}return(d)?b:"#"+b.join("");}function (b){if(this.length!=3){return null; }var a=this.map(function(c){if(c.length==1){c+=c;}return c.toInt(16);});return(b)?a:"rgb("+a+")";}function (){for(var b=0,a=this.length;b</p>
The above code is not mine, it is the output of an "error" I have when I press the button to get credits, I do not have such lines nowhere in my source code and it is cut off at the end because it shows to me this way (firebug gave me whole part as stated above)
I don't have such lines in my code and this happens when for example I want to click on a button that will give me credit by clicking onto it (clicking game, You click on the button it will give You credit):
function credit() {
var a = game.credit+=100;
document.getElementById("add").innerHTML=Fix(a);
}
Do I have this problem because I need to use some other function/rewrite my code for PHP ? Or is it because I need to use some push function, or do I have something wrong with my apache? Or it's because of the document.getElementById and I should write it differently while using PHP?
Ps: game.credit because it's using different function too, and Fix(a) because it's using other function to beautify the result. Every other functions are working, only the ones that are responsible for adding the credit are showing me this text.
This is Fix function:
function Fix(what){
var str='';
what=Math.floor(what);
what=(what+'').split('').reverse();
for (var i in what) {
if (i%3==0 && i>0) str = ','+str;
str = what[i]+str;
}
return str;
}
#Edit
Ok I just did check it and it's this Fix function causing problem, everything works fine when I do not use it (for example I do: "document.getElementById("add").innerHTML=a;"). So what's wrong with this fix function, can someone help me make it work? This function is changing the numbers in example 1000 to 1,000 and not allowing it to be like 503.0203

Chrome JavaScript location object

I am trying to start 3 applications from a browser by use of custom protocol names associated with these applications. This might look familiar to other threads started on stackoverflow, I believe that they do not help in resolving this issue so please dont close this thread just yet, it needs a different approach than those suggested in other threads.
example:
ts3server://a.b.c?property1=value1&property2=value2
...
...
to start these applications I would do
location.href = ts3server://a.b.c?property1=value1&property2=value2
location.href = ...
location.href = ...
which would work in FF but not in Chrome
I figured that it might by optimizing the number of writes when there will be effectively only the last change present.
So i did this:
function a ()
{
var apps = ['ts3server://...', 'anotherapp://...', '...'];
b(apps);
}
function b (apps)
{
if (apps.length == 0) return;
location.href = apps[0]; alert(apps[0]);
setTimeout(function (rest) {return function () {b(rest);};} (apps.slice(1)), 1);
}
But it didn't solve my problem (actually only the first location.href assignment is taken into account and even though the other calls happen long enough after the first one (thanks to changing the timeout delay to lets say 10000) the applications do not get started (the alerts are displayed).
If I try accessing each of the URIs separately the apps get started (first I call location.href = uri1 by clicking on one button, then I call location.href = uri2 by clicking again on another button).
Replacing:
location.href = ...
with:
var form = document.createElement('form');
form.action = ...
document.body.appendChild(form);
form.submit();
does not help either, nor does:
var frame = document.createElement('iframe');
frame.src = ...
document.body.appendChild(frame);
Is it possible to do what I am trying to do? How would it be done?
EDIT:
a reworded summary
i want to start MULTIPLE applications after one click on a link or a button like element. I want to achieve that with starting applications associated to custom protocols ... i would hold a list of links (in each link there is one protocol used) and i would try to do "location.src = link" for all items of the list. Which when used with 'for' does optimize to assigning only once (the last value) so i make the function something like recursive function with delay (which eliminates the optimization and really forces 3 distinct calls of location.src = list[head] when the list gets sliced before each call so that all the links are taken into account and they are assigned to the location.src. This all works just fine in Mozilla Firefox, but in google, after the first assignment the rest of the assignments lose effect (they are probably performed but dont trigger the associated application launch))
Are you having trouble looping through the elements? if so try the for..in statement here
Or are you having trouble navigating? if so try window.location.assign(new_location);
[edit]
You can also use window.location = "...";
[edit]
Ok so I did some work, and here is what I got. in the example I open a random ace of spades link. which is a custom protocol. click here and then click on the "click me". The comments show where the JSFiddle debugger found errors.

Categories

Resources