I'm using MonkeyTalk IDE Beta2 for testing iPad application. I exported the javascript from the MonkeyTalk IDE and got a new .js file. I am storing the Boolean value of a Verify command in a var and want to see what is its value, and accordingly do custom logic. I tried document.write, console.log and alert used in javascript but got an error that they are not defined. Please help me with this.
Also, is it possible to output the result of a test as XML (as in FoneMonkey) or as an Excel spreadsheet or something like that?
Thank you in advance.
Believe it or not*, but to date there is no way direct way to cause MonkeyTalk to log messages to the console. What you can do, however, is abuse a command like verifyNot which will result in a log message. In a MonkeyTalk .mt this would be done like:
View * VerifyNot Message
I created the following helper script called log.js for this purpose. Timestamps are automatically added by Eclipse, but not elsewhere so I have prepended the time.
load("libs/Executor.js");
function getTimeStamp() {
var now = new Date();
return now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds();
}
EXECUTOR.defineScript("Log", function(msg) {
this.app.view().verifyNot(getTimeStamp() + ": " + msg);
});
Finally, you don't need the executor boilerplate (only the verifyNot line), but we use that with scripts by Doba in order to be able to organize files in different directories (Doba.js renamed to Executor.js) -- another feature not available out of the box.
* It's almost like GorillaLogic doesn't want you to be able to resolve your own problems. ;)
Related
I have written a web-crawler to test a pre-release website for errors and issues (i.e. missing content type, timeouts, exceptions, redirects).
This morning a colleague asked me to include a check if there was any javascript error on the page...
A pure javascript solution is unlikely -- i.e. detect all JS errors, using JS
What I appear to want to be able to do is capture the javascript console text, ideally via CoreWebView2
If the page logs each exception into an array,
Errors=[]
window.onerror = function (msg, url, line) {
Errors.push("Caught[via window.onerror]: '" + msg + "' from " + url + ":" + line);
return true;
};
Then you can just query the Errors and see both the count and the nature of the errors.
You can also push errors from try catch
I've seen some answers to this that refer the askee to other libraries (like phantom.js), but I'm here wondering if it is at all possible to do this in just node.js?
Considering my code below. It requests a webpage using request, then using cheerio it explores the dom to scrape the page for data. It works flawlessly and if everything had gone as planned, I believe it would have outputted a file as i imagined in my head.
The problem is that the page I am requesting in order to scrape, build the table im looking at asynchronously using either ajax or jsonp, i'm not entirely sure how .jsp pages work.
So here I am trying to find a way to "wait" for this data to load before I scrape the data for my new file.
var cheerio = require('cheerio'),
request = require('request'),
fs = require('fs');
// Go to the page in question
request({
method: 'GET',
url: 'http://www1.chineseshipping.com.cn/en/indices/cbcfinew.jsp'
}, function(err, response, body) {
if (err) return console.error(err);
// Tell Cherrio to load the HTML
$ = cheerio.load(body);
// Create an empty object to write to the file later
var toSort = {}
// Itterate over DOM and fill the toSort object
$('#emb table td.list_right').each(function() {
var row = $(this).parent();
toSort[$(this).text()] = {
[$("#lastdate").text()]: $(row).find(".idx1").html(),
[$("#currdate").text()]: $(row).find(".idx2").html()
}
});
//Write/overwrite a new file
var stream = fs.createWriteStream("/tmp/shipping.txt");
var toWrite = "";
stream.once('open', function(fd) {
toWrite += "{\r\n"
for(i in toSort){
toWrite += "\t" + i + ": { \r\n";
for(j in toSort[i]){
toWrite += "\t\t" + j + ":" + toSort[i][j] + ",\r\n";
}
toWrite += "\t" + "}, \r\n";
}
toWrite += "}"
stream.write(toWrite)
stream.end();
});
});
The expected result is a text file with information formatted like a JSON object.
It should look something like different instances of this
"QINHUANGDAO - GUANGZHOU (50,000-60,000DWT)": {
"2016-09-29": 26.7,
"2016-09-30": 26.8,
},
But since the name is the only thing that doesn't load async, (the dates and values are async) I get a messed up object.
I tried Actually just setting a setTimeout in various places in the code. The script will only be touched by developers that can afford to run the script several times if it fails a few times. So while not ideal, even a setTimeout (up to maybe 5 seconds) would be good enough.
It turns out the settimeouts don't work. I suspect that once I request the page, I'm stuck with the snapshot of the page "as is" when I receive it, and I'm in fact not looking at a live thing I can wait for to load its dynamic content.
I've wondered investigating how to intercept the packages as they come, but I don't understand HTTP well enough to know where to start.
The setTimeout will not make any difference even if you increase it to an hour. The problem here is that you are making a request against this url:
http://www1.chineseshipping.com.cn/en/indices/cbcfinew.jsp
and their server returns back the html and in this html there are the js and css imports. This is the end of your case, you just have the html and that's it. Instead the browser knows how to use and to parse the html document, so it is able to understand the javascript scripts and to execute/run them and this is exactly your problem. Your program is not able to understand that has something to do with the HTML contents. You need to find or to write a scraper that is able to run javascript. I just found this similar issue on stackoverflow:
Web-scraping JavaScript page with Python
The guy there suggests https://github.com/niklasb/dryscrape and it seems that this tool is able to run javascript. It is written in python though.
You are trying to scrape the original page that doesn't include the data you need.
When the page is loaded, browser evaluates JS code it includes, and this code knows where and how to get the data.
The first option is to evaluate the same code, like PhantomJS do.
The other (and you seem to be interested in it) is to investigate the page's network activity and to understand what additional requests you should perform to get the data you need.
In your case, these are:
http://index.chineseshipping.com.cn/servlet/cbfiDailyGetContrast?SpecifiedDate=&jc=jsonp1475577615267&_=1475577619626
and
http://index.chineseshipping.com.cn/servlet/allGetCurrentComposites?date=Tue%20Oct%2004%202016%2013:40:20%20GMT+0300%20(MSK)&jc=jsonp1475577615268&_=1475577620325
In both requests:
_ is a decache parameter to prevent caching.
jc is a name of a JS wrapper function which should be invoked with the result (https://en.wikipedia.org/wiki/JSONP)
So, scrapping the table template at http://www1.chineseshipping.com.cn/en/indices/cbcfinew.jsp and performing two additional requests you will be able to combine them into the same data structure you see in the browser.
When I click on a certain link the server writes if I have done it by stating either true or false in a text file...
Just like this:
{"needs_click":false,"has_clicked":false,"sites":[{"id":2134,"name":"testing","has_clicked":false,"click_url":"http://testing.com?siteid=5433"}]}
Now what I have done is uploaded a text file to my FTP already and changed all the false results into true like this:
{"needs_click":true,"has_clicked":true,"sites":[{"id":2134,"name":"testing","has_clicked":true,"click_url":"http://testing.com?siteid=5433"}]}
Now in one of the JavaScript files attached to the source code there is the variable at the top directing to the text file I just need to know how to make my browser read the spoofed link I created instead of the original.
I need to change the variables:
var API_VERSION = 0.1;
var API_URL = "http://api.testwebsite.com/" + API_VERSION + "/";
To:
var API_VERSION = 0.1;
var API_URL = "http://api.testwebsite2.com/" + API_VERSION + "/";
So it reads the other text file stating all the true options instead of the original... any suggestions?
What if you used a personal proxy to shape the query? Something like Charles proxy could work. In any case you will need to get in between the browser and server to do this sort of thing.
Alternatively you could try to rewrite entire JavaScript (ie. remove the original from source before loading and inject your own with the url fixed, you might be able to get away with a replace on the original). I don't know how feasible this is, though, as I don't know internals of Greasemonkey well enough. But this might be something to explore.
Was impossible, at the time I was very new to programming and limitations on what I could and could not do.
I'm trying to write headless integration tests for every page on my site in CoffeeScript/Javascript and run them in one command. I've tried using casperjs but I keep running into issues When attempting to run more than one test suite in a loop of requests.
Ideally I'd like to do something like this:
for page in ['/products','/about', '/contact']
open(page, ->
require("tests/#{page}/test.coffee").execute()
Where the test file looks something like:
exports.execute ->
test.assert(pageTitleIs('about us'))
So that I could keep tests for each page in separate files, but run them all heedlessly with one command.
casper.thenOpen( url, ->
#CurrentUrl = url
#currentRoute = route
#test.currentSuite = #test.running = #test.started = false # Hack. If we don't do this and a test fails, no tests after it will be executed
#test.info("Testing #{urlPath}");
path = currentDirectory+'/root'+route;
if(fs.isDirectory(path))
for file in fs.list(path)
if(file.indexOf('.spec')!=-1)
#echo 'executing file: ' + path + '/'+ file
#test.exec(path + '/'+ file);
#test.exec currentDirectory+"/smoke.test.js"
#waitFor ->
if test_done #Hack. If we don't do this, new tests will start before old ones finished.
return true
test_done = false
)
This is the solution I came up with, where smoke.test.js gets executed for every page. It's pretty hacky and I've run into many issues related to the scope of the tests, but it works.
String interpolation does not work with single quotes. You have to use double-quotes. See the difference:
require('tests/#{page}/test.coffee').execute()
# becomes: require('tests/#{page}/test.coffee').execute();
require("tests/#{page}/test.coffee").execute()
# becomes: require("tests/" + page + "/test.coffee").execute();
I've been struggling with this and can't find a single tutorial on what seems to be a very simple idea.
I've written to the settings in the settings.html file using:
System.Gadget.Settings.writeString("Date1", month + "-" + day + "-" + year);
And that seems to have worked. It displays properly in the settings.
Now, in the main file, gadget.html, I want to pull the data out and display it (not in an input tag). What is the complete code to do this?
Write it to an xml file and use ajax to read it.
Alternatively, write it to a .js file and import it with a <script src=...></script> construct.