How to preserve long numbers in CasperJS when using command line options? - javascript

When doing this:
casperjs somescript.js --number=736280854938322517687376855643288785
and in the code:
var casper = require('casper').create();
var value = casper.cli.get("number");
console.log(value); // yields: 7.3628085493832246e+35
// want: 736280854938322517687376855643288785
I've looked and looked, pondered and hacked, but I'm not having much luck. The easy solution seems to be simply converting the number into a string. Or passing the number in as a string. But the syntax for this eludes me.

See Raw parameter values:
By default, the cli object will process every passed argument & cast them to the appropriate detected type[...]
You need to use casper.cli.raw.get("number") to get a non-parsed value. Since integer values that are bigger than 253 cannot be represented as an integer without losing precision, you would need to work with them as a string or use some big integer library (such as JSBN).

Related

Decompressing bzip2 data in Javascript

I ultimately have to consume some data from a Javascript file that looks as follows:
Note: The base64 is illustrative only.
function GetTripsDataCompressed() { return 'QlpoOTFBWSZTWdXoWuEDCAgfgBAHf/.....=='; }
GetTripsDataCompressed() returns a base64 string that is derived as an array of objects converted to JSON using JSON.NET and the resulting string then compressed to bzip2 using SharpCompress with the resulting memory stream Base64 encoded.
This is what I have and cannot change it.
I am struggling to find a bzip2 JavaScript implementation that will take the result of:
var rawBzip2Data = atob(GetTripsDataCompressed());
and convert rawBzip2Data back into the string that is the JSON array. I cannot use something like compressjs as I need to support IE 10 and as it uses typed arrays that means IE10 support is out.
So it appears that my best option is https://github.com/antimatter15/bzip2.js however because I have not created an archive and only bzip2 a string it raises an error of Uncaught No magic number found after doing:
var c = GetTripsDataCompressed();
c = atob(c);
var arr = new Uint8Array(c);
var bitstream = bzip2.array(arr);
bzip2.simple(bitstream);
So can anyone help me here to decompress a BZip2, Base64 encoded string from JavaScript using script that is IE 10 compliant? Ultimately I don't care whether it uses https://github.com/antimatter15/bzip2.js or some other native JavaScript implementation.
It seems to me the answer is in the readme:
decompress(bitstream, size[, len]) does the main decompression of a single block. It'll return -1 if it detects that it's the final block, otherwise it returns a string with the decompressed data. If you want to cap the output to a certain number of bytes, set the len argument.
Also, keep in mind the repository doesn't have a license attached. You'll need to reach out to the author if you want to use the code. That might be tricky given that the repository is eight years old.
On the other hand, the Bzip2 algorithm itself is open-source (BSD-like license), so you can just reimplement it yourself in Javascript. It's just a few hundred lines of relatively straight-forward code.

Google Earth Engine ee.Number to integer

This is probably a simple question for people familiarized with the Code Editor of Google Earth Engine (https://code.earthengine.google.com/) or generally Javascript.
In my code, I need to use the size of an object for a boolean conditional (e.g. n>0). However, the output of .size() which I would store in n does not return a plain integer, but a ee.Number structure and I am not being able to transform it into an integer to properly evaluate the conditional.
Example with the structure ee.Number of Earth Engine:
var n=ee.Number(1)
print(n)
print(n.int())
print(n==1)
print(n===1)
print(n.int()==1)
print(n.int()===1)
print(n.int()== parseInt(1))
This outputs these evaluate as false, even when I try to tast the number structure into an int.
1
1
false
false
false
false
false
note:
print(typeof n)
returns an object (JSON):
object
Any help very much appreciated. Thanks
This is due to how GEE works. Processing steps are constructed locally as objects and then only evaluated by the server once another function requires it.
print is one of the functions that requires execution, this is why it shows as integer in your console.
You can force evaluation with .getInfo()... this however should be used with caution, because everything is pulled to the client side, which can be problematic with big objects.
So this works:
var n=ee.Number(1)
print(n)
print(n.getInfo()==1)
giving
1
true
This section of the documentation explains the background.
If the value of n indeed is JSON, try to parse it:
n = JSON.parse(n);
Then convert it into an integer:
n = parseInt(n);

Passing number variable through CasperJS command line leads to some character instead of the number

I have a basic CasperJS script, that inserts a pre-defined search term in to the amazon search box, and when I execute the script and look at the captured image I can see the text in the box fine.
I then decided to make it dynamic and instead of pre-defining the search term I pass it though the command line like so.
casperjs amazon.js --barcode=4380758484375
However, when I do this I get no text in the search field on the amazon site when I look at the captured image. I know the value is being passed as I have echo'ed it.
My experience with very limited and started learning this weekend, I'm wondering if I need to define the var at all. For testing purposes barcode is set to the value being passed through the command line, and barcode1 is pre-defined.
var casper = require('casper').create();
var x = require('casper').selectXPath;
casper.userAgent('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');
casper.echo("Casper CLI passed args:");
require("utils").dump(casper.cli.args);
casper.echo("Casper CLI passed options:");
require("utils").dump(casper.cli.options);
var barcode = casper.cli.get("barcode");
var barcode1 = "5030945112877"; //casper.cli.get("barcode");
casper.echo("*"+barcode1+"*");
casper.start('https://www.amazon.co.uk/');
casper.then(function () {
this.sendKeys('#twotabsearchtextbox', barcode);
console.log('Entering Search Term '+barcode+' Into Amazon Search Field');
casper.capture('amazon.png');
});
casper.run();
If I set --barcode=fifa it works. If I set it to --barcode=fifa123 it also works, but if I set it to --barcode=123, in the capture image I see an extended char corresponding to the 123.
See Raw parameter values:
By default, the cli object will process every passed argument & cast them to the appropriate detected type[...]
CasperJS automatically parses CLI options into appropriate types. If you type in a number, it will be converted to a number. This is not problematic as-is, but since this number is passed into casper.sendKeys() it is not treated as a string. casper.sendKeys() is a wrapper around PhantomJS' page.sendEvent(), which treats integers are char codes.
You need to use the raw value or convert to string yourself:
var barcode = casper.cli.raw.get("barcode");
// or
var barcode = "" + casper.cli.get("barcode");
after a bit of trail and error it seems passing a number only through the command line is where the problem exists.
by using
casper.cli.raw.get("barcode");
instead of
casper.cli.get("barcode");
resolved the problem, this is due to a chance in the CasperJS version that i can see. Also found reference to the following site https://github.com/casperjs/casperjs/issues/248

Selenium javascript approximate value

I'am experimenting with selenium IDE and i came across a problem with asserting an approximate value. I need to check a value inside an element with an id. It is numeric value with comma (",") as a separator.
Problem is that i need to check if the numeric value is valid with a tolerance of 0.01.
For example:
<div id="uniqueId">2,54</div>
assertText - value = 2.53
I need above example to pass the test, and also pass if the value in div si 2,52 or 2,53. I understand that i can use assertEval to insert javascript, but i'm not very good in javascript and also from what i've read the javascript capabilities of selenium are limited.
Any help would be greatly appreciated!
Using assertEval is a good idea. The javascript you will need will be something like
var numberStr = "${actualText}".replace(",", ".");
var number = parseFloat(numberStr);
var difference = Math.abs(eval(number-${expectedValue}));
(difference <= 0.01)?true:false;
I don't know much javascript but according to this thread we need to first replace decimal mark from ',' to '.' (1st line) so we can later convert the string found on page to number (2nd line).
${actualText} is a variable in which we store the actual value taken from page while the ${expectedValue} is a value you need to define on your own. Note that tolerance (0.01) is "hardcoded", you may want to replace it with variable too.
Now to make it shorter (and less readable):
(Math.abs(eval(parseFloat("${actualText}".replace(",", "."))-${expectedValue}))<=0.01)?true:false
Having the javascript we can prepare Selenium script:
storeText | id=uniqueId | actualText
store | 2.53 | expectedValue
assertEval | JS LINE FORM ABOVE GOES HERE | true

less.js - get variable values inside parsers' callback

I am using less.js (1.3.0) to parse less to css on the client side. Inside the parsers' callback I want to get the value for each variable. i tried the following without success.
var data = "#colour: red; #example { background-color: #colour; }",
parser = new less.Parser({});
parser.parse(data, function (error, root) {
console.log( root.toCSS() );
var varsDef = root.variables();
for (k in varsDef) {
console.log(varsDef[k]);
// how to get the value for the var?
//not working
console.log(varsDef[k].eval());
//not working
console.log(varsDef[k].toCSS());
//is an object but looking for a string value
console.log(varsDef[k].value);
//returns an empty string
console.log(varsDef[k].value.toCSS());
}
});
Neither eval() nor the toCSS() gave me any results. I do not understand the less parsers' inner workings. Each variable object has a variable property varsDef[k].value which is an object itself. But I just need the string value of the variable.
Does anyone know how to get the variables' values as a string?
varsDef[k].value.toCSS()
should be the value
varsDef[k].name
should be the variable name
varsDef[k].toCSS()
returns nothing because it is a variable - in CSS variables do not output.
i ran into this problem recently and it bit me because, like you, i had the same instinct of running something like very much like the code you wrote above but for complex variables along the lines of
#redColor: #900; // responds to .toCSS()
#fooColor: desaturate(#redColor, 20%); // both of these error out
#barColor: lighten(#fooColor, 10%); // when calling .toCSS()
you'd get this nested tree.Value for #barColor which was this nested representation of the parse tree, so it would say, unhelpfully that barcolor: {[value: {value: [{lighten: {...}}]}]} or somesuch. my parsing-fu is pretty bad because i would always end up with some object at some point which would no longer respond to me invoking tree.toCSS on it, so i gave up on that route.
Instead, what i did was generated a nonsense .less file with an import rule and a nonsense rule, like so
#import "varfile.less";
.foo {
redColor: #redColor;
fooColor: #fooColor;
barColor: #barColor;
}
less will happily parse such a file, it doesn't care if redColor is a real css property or not, it just ignores it and does all the substitutions where it has to dutifully. And so you actually end up with a single rule css file that you can easily parse since it's very straightforwardly marked up. it looks like this:
.foo{
redColor: #990000;
fooColor: #8a0f0f;
barColor: #b81414;
}
this is, coincidentally, the easiest file to parse. it practically begs to be turned into json or what have you. granted, the path to here is pretty comical. i suspect it's because a variable without a rule is still fair game to be modified within the rule itself, but i could just be rationalizing that.
assuming you only want to extract the final values of your less vars and not the semantic values of your less vars, it's pretty handy. if you want semantics, it seems better to just parse the actual less file.
i ended up writing this in node and after i got past my own objections to how dodgy it felt, it worked quite well and fed me a json dict with my project's variables. you can take a look, it's on github at nsfmc/less-extractor which basically takes a basic config file and then writes to stdout a json dict. it's inelegant, but it totally works, even if it's a bit hackish.
your original question asked about doing this entirely client-side, so that would appear to rule out that github project, but the idea is very similar: you want to be able to access the original less file as part of some xhr request, parse it to get the variable names, build a less string, parse that, and then the rest of the code is just string building and run of the mill parsing.
hope that helps you!
I was also having issues with the less parser too; doing it that way was getting ridiculous with recursive checking of tree nodes.
If you wan't the actual values as opposed to the CSS generated (as per the above answer), the best way is to probably manually parse the file's text.
This function returns a key/value pair for each of the variables in a given less file. It wont work if the LESS file has multiple values per line, you could make it better with regex. I used it to parse bootstrap's variables file, which works nicely.
getLessVars = (lessStr) ->
lines = lessStr.split('\n')
lessVars = {}
for line in lines
if line.indexOf('#') is 0
keyVar = line.split(';')[0].split(':')
lessVars[keyVar[0]] = keyVar[1].trim()
return lessVars

Categories