Accessing local files in offline jquery app - javascript

I'm a beginner trying to use jquery to build an app (mostly offline), I'm developing it using chrome/firefox I want to have a local .txt file with some data stored in it as an array. However, I can't seem to access it. The ajax function never succeeds.
(document).ready(function () {
local_list_dict = ['Example', 'Example 2', 'Example 3'];
online_list_dict = ['Park', 'running'];
$('#master_set').on('click', function () {
$.ajax({ //this does not work
url: "/local/pg/document1.txt",
success: function (data) {
alert('success');
},
});
for (i = 0; i < local_list_dict.length; i++) {
$('#local_list').append("<li class='idea_list'><a href='#player_1' rel='external'>" + local_list_dict[i] + "</a></li>");
}
;
$('#local_list').listview('refresh');
});
$('#home').hide().fadeToggle(500);
$('.idea_list').on('click', function () {
alert('debug')
var panelId = $(this).text(); // some function to pass player_1 the contents of the list
$('#chosen_list').html();// some function that takes panelId and uses it to choose the relevant .txt file
});
});

I tried do the same thing, but I don't got some good results duo the security rules. There are some tricks to help you to try, but the best to do is run your script in a local server (you can do it with the WampServer or other tools).
Some interesting links that can help you:
https://stackoverflow.com/a/372333/3126013
https://stackoverflow.com/a/19902919/3126013
http://www.html5rocks.com/en/tutorials/file/dndfiles/

An easy way is by running your project/app in a local server such as Node.js or even more easy for you, by using the extension Chrome Dev Editor (developer preview) --
Chrome Dev Editor (CDE) is a developer tool for building apps on the Chrome platform - Chrome Apps and Web Apps. CDE has support for writing applications in JavaScript or Dart, and has Polymer templates to help you get started building your UI. CDE also has built-in support for Git, Pub and Bower.
Personally, I prefer run my local apps in Node.js

Related

use .net dll in electron

I am a .NET developer and new to electron and node.js.
From my electron application, I need to call one function inside a .NET class library DLL which will generate some document and will send to print.
I need to use this electron application only on the windows machine. I see plugin Edge.js, but am not sure this will work for me and also don't know how to include in my project.
Edge.js will do the trick.
See the following snippet:
var edge = remote.require('electron-edge');
var toErMahGerd = edge.func({
assemblyFile: 'ERMAHGERD.dll',
typeName: 'ERMAHGERD.Translate',
methodName: "ToErMahGerd"
});
document.getElementById("translate-btn").addEventListener("click", function (e) {
var inputText = document.getElementById("input-text").value;
toErMahGerd(inputText, function (error, result) {
document.getElementById("output-text").innerHTML = result;
});
});
And here is the GitHub-repo with not only good docs to dive in but a simple getting started.

Which javascript Automated Testing Tool to use

I am looking for an npm/javascript based Automated Testing tool with which I can test my website providing scripted input values and then for example clicking submit button on page etc.
So far I have tested Dalekjs but it seems to have lots of problems especially with Firefox, plus some CSS selectors are also not working even in other Browsers.
Is there any other good Automation testing tool that is npm based but does not necessarily require Selenium?
Nightmare.js
There's a really awesome tool called Nightmare.js. First it was a hight-level Phantom wrapper, but since v2 it was rewritten on Atom. Nightmare is webkit-based.
Nightmare can be executed headlessly, but you'll probably need to configure your server to get that working.
Why Nightmare? Here's a code sample from the official site:
Nightmare.js
yield Nightmare()
.goto('http://yahoo.com')
.type('input[title="Search"]', 'github nightmare')
.click('.searchsubmit');
Comparing to:
Phantom.js
phantom.create(function (ph) {
ph.createPage(function (page) {
page.open('http://yahoo.com', function (status) {
page.evaluate(function () {
var el =
document.querySelector('input[title="Search"]');
el.value = 'github nightmare';
}, function (result) {
page.evaluate(function () {
var el = document.querySelector('.searchsubmit');
var event = document.createEvent('MouseEvent');
event.initEvent('click', true, false);
el.dispatchEvent(event);
}, function (result) {
ph.exit();
});
});
});
});
});
So you'll have to write significantly less code.
BUT IT'S WEBKIT-ONLY
Selenium
In order to get something working in all browsers, take a look at Selenium. It supports really many browsers and platforms.
var webdriver = require('selenium-webdriver'),
By = require('selenium-webdriver').By,
until = require('selenium-webdriver').until;
var driver = new webdriver.Builder()
.forBrowser('firefox')
.build();
driver.get('http://www.google.com/ncr');
driver.findElement(By.name('q')).sendKeys('webdriver');
driver.findElement(By.name('btnG')).click();
driver.wait(until.titleIs('webdriver - Google Search'), 1000);
driver.quit();
Just a small advice Selenium tests are likely to be more "bulky" than nightmare tests and I've seen quite a lot "Promise hell" in Selenium tests on one of my previous jobs, so before you start, my advice to you would be to use of generators and co or some other control flow library.
try http://phantomjs.org/
It might be an excellent alternative to Dalekjs. Phantom.js is runnable without a UI, scriptable via JavaScript and is used for automating web page interaction. It's a WebKit with its own JavaScript API. It has fast and native support for most web standards: DOM handling, CSS selector, JSON, Canvas, and SVG. You can use scripted input values
Here is a sample usage:
console.log('Loading a web page');
var page = require('webpage').create();
var url = 'http://en.wikipedia.org/';
page.open(url, function (status) {
console.log('Page loaded');
page.render('wikipedia.org.png');
phantom.exit();
});
I also had a similar requirement, I did below investigation which would be helpful:
NightmareJS is actually based on PhantomJS. It works very well even for a non-dev. In reality automated testing truly depends on many situations and the type of application tested. You need a super fast way to visually see if changes to the code is affecting the app visually and also to some degree its logic. For logic there are many other frameworks for that like selenium frameworks. No need for complex coding as you want to be able to view the application or test results quick, modify the variable or elements that neeeds to be tested and verified.

Meteor: Authenticating Chrome Extension via DDP

I've built a Chrome Extension that takes a selection of text and when I right click and choose the context menu item, it sends that text to my Meteor app. This works fine, however, I can't figure out the process of using Oauth to authenticate users.
I'm using this package: https://github.com/eddflrs/meteor-ddp
Here is the JS within background.js (for Chrome Extension):
var ddp = new MeteorDdp("ws://localhost:3000/websocket");
ddp.connect().then(function() {
ddp.subscribe("textSnippets");
chrome.runtime.onMessage.addListener(function(message) {
ddp.call('transferSnippet', ['snippetContent', 'tag', snippetString]);
});
});
Here is the relevant portion of my other JS file within my Chrome Extension:
function genericOnClick(info) {
snippetString = [];
snippetString.push(info.selectionText);
var snippetTag = prompt('tag this thing')
snippetString.push(snippetTag);
chrome.runtime.sendMessage(snippetString);
}
And here is the relevant portion of my Meteor app:
'transferSnippet': function(field1, field2, value1, value2) {
var quickObject = {};
quickObject.field1 = value1[0];
quickObject.field2 = value1[1];
TextSnippets.insert({
snippetContent: value1[0],
tag: value1[1]
});
}
Basically I'm stuck and don't know how to go about making a DDP call that will talk to my Meteor app in order to authenticate a user
This question is a bit old, but if anyone is still looking for a solution. I had a similar problem that I was able to solve using the following plugin: https://github.com/mondora/asteroid. Here is an example of how to do it for twitter oauth:
https://github.com/mondora/asteroid/issues/41#issuecomment-72334353

Simplest way to launch Firefox, drive 3rd party site using privileged nsI* APIs

What's the simplest way to launch Firefox, load a 3rd party website (which I'm authorised to "automate"), and run some "privileged" APIs against that site? (e.g: nsIProgressListener, nsIWindowMediator, etc).
I've tried a two approaches:
Create a tabbed browser using XULrunner, "plumbing" all the appropriate APIs required for the 3rd party site to open new windows, follow 302 redirects, etc. Doing it this way, it's an aweful lot of code, and requires (afaict) that the user installs the app, or runs Firefox with -app. It's also extremely fragile. :-/
Launch Firefox passing URL of the 3rd party site, with MozRepl already listening. Then shortly after startup, telnet from the "launch" script to MozRepl, use mozIJSSubScriptLoader::loadSubScript to load my code, then execute my code from MozRepl in the context of the 3rd party site -- this is the way I'm currently doing it.
With the first approach, I'm getting lots of security issues (obviously) to work around, and it seems like I'm writing 10x more browser "plumbing" code then automation code.
With the second approach, I'm seeing lots of "timing issues", i.e:
the 3rd party site is somehow prevented from loading by MozRepl (or the execution of the privileged code I supply)???, or
the 3rd party site loads, but code executed by MozRepl doesn't see it load, or
the 3rd party site loads, and MozRepl isn't ready to take requests (despite other JavaScript running in the page, and port 4242 being bound by the Firefox process),
etc.
I thought about maybe doing something like this:
Modify the MozRepl source in some way to load privileged JavaScript from a predictable place in the filesystem at start-up (or interact with Firefox command-line arguments) and execute it in the context of the 3rd party website.
... or even write another similar add-on which is more dedicated to the task.
Any simpler ideas?
Update:
After a lot of trial-and-error, answered my own question (below).
I found the easiest way was to write a purpose-built Firefox extension!
Step 1. I didn't want to do a bunch of unnecessary XUL/addon related stuff that wasn't necessary; A "Bootstrapped" (or re-startless) extension needs only an install.rdf file to identify the addon, and a bootstrap.js file to implement the bootstrap interface.
Bootstrapped Extension: https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions
Good example: http://blog.fpmurphy.com/2011/02/firefox-4-restartless-add-ons.html
The bootstrap interface can be implemented very simply:
const path = '/PATH/TO/EXTERNAL/CODE.js';
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
var loaderSvc = Cc["#mozilla.org/moz/jssubscript-loader;1"];
.getService(Ci.mozIJSSubScriptLoader);
function install() {}
function uninstall() {}
function shutdown(data, reason) {}
function startup(data, reason) { loaderSvc.loadSubScript("file://"+path); }
You compile the extension by putting install.rdf and bootstrap.js into the top-level of a new zip file, and rename the zip file extension to .xpi.
Step 2. To have a repeatable environment for production & testing, I found the easiest way was to launch Firefox with a profile dedicated to the automation task:
Launch the Firefox profile manager: firefox -ProfileManager
Create a new profile, specifying the location for easy re-use (I called mine testing-profile) and then exit the profile manager.
Remove the new profile from profiles.ini in your user's mozilla config (so that it won't interfere with normal browsing).
Launch Firefox with that profile: firefox -profile /path/to/testing-profile
Install the extension from the file-system (rather than addons.mozilla.org).
Do anything else needed to prepare the profile. (e.g: I needed to add 3rd party certificates and allow pop-up windows for the relevant domain.)
Leave a single about:blank tab open, then exit Firefox.
Snapshot the profile: tar cvf testing-profile-snapshot.tar /path/to/testing-profile
From that point onward, every time I run the automation, I unpack testing-profile-snapshot.tar over the existing testing-profile folder and run firefox -profile /path/to/testing-profile about:blank to use the "pristine" profile.
Step 3. So now when I launch Firefox with the testing-profile it will "include" the external code at /PATH/TO/EXTERNAL/CODE.js on each start-up.
NOTE: I found that I had to move the /PATH/TO/EXTERNAL/ folder elsewhere during step 2 above, as the external JavaScript code would be cached (!!! - undesirable during development) inside the profile (i.e: changes to the external code wouldn't be seen on next launch).
The external code is privileged and can use any of the Mozilla platform APIs. There is however an issue of timing. The moment-in-time at which the external code is included (and hence executed) is one at which no Chrome window objects (and so no DOMWindow objects) yet exist.
So then we need to wait around until there's a useful DOMWindow object:
// useful services.
Cu.import("resource://gre/modules/Services.jsm");
var loader = Cc["#mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader);
var wmSvc = Cc["#mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator);
var logSvc = Cc["#mozilla.org/consoleservice;1"]
.getService(Ci.nsIConsoleService);
// "user" code entry point.
function user_code() {
// your code here!
// window, gBrowser, etc work as per MozRepl!
}
// get the gBrowser, first (about:blank) domWindow,
// and set up common globals.
var done_startup = 0;
var windowListener;
function do_startup(win) {
if (done_startup) return;
done_startup = 1;
wm.removeListener(windowListener);
var browserEnum = wm.getEnumerator("navigator:browser");
var browserWin = browserEnum.getNext();
var tabbrowser = browserWin.gBrowser;
var currentBrowser = tabbrowser.getBrowserAtIndex(0);
var domWindow = currentBrowser.contentWindow;
window = domWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
gBrowser = window.gBrowser;
setTimeout = window.setTimeout;
setInterval = window.setInterval;
alert = function(message) {
Services.prompt.alert(null, "alert", message);
};
console = {
log: function(message) {
logSvc.logStringMessage(message);
}
};
// the first domWindow will finish loading a little later than gBrowser...
gBrowser.addEventListener('load', function() {
gBrowser.removeEventListener('load', arguments.callee, true);
user_code();
}, true);
}
// window listener implementation
windowListener = {
onWindowTitleChange: function(aWindow, aTitle) {},
onCloseWindow: function(aWindow) {},
onOpenWindow: function(aWindow) {
var win = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
win.addEventListener("load", function(aEvent) {
win.removeEventListener("load", arguments.callee, false);
if (aEvent.originalTarget.nodeName != "#document") return;
do_startup();
}
};
// CODE ENTRY POINT!
wm.addListener(windowListener);
Step 4. All of that code executes in the "global" scope. If you later need to load other JavaScript files (e.g: jQuery), call loadSubscript explicitly within the null (global!) scope
function some_user_code() {
loader.loadSubScript.call(null,"file:///PATH/TO/SOME/CODE.js");
loader.loadSubScript.call(null,"http://HOST/PATH/TO/jquery.js");
$ = jQuery = window.$;
}
Now we can use jQuery on any DOMWindow by passing <DOMWindow>.document as the second parameter to the selector call!

Platform-Independent JS->Native Bridge?

I'm currently working on an app that aggressively uses webviews on both iOS and Android to render content, with native chrome surrounding it. I want to be able to control this chrome via javascript methods.
Android Webview has addJavascriptInterface which allows this to happen, but iOS does not have this facility. I've already checked out the SO answer at iOS JavaScript bridge, and this has usefuleinformation, but It's iOS-only; optimally the same underlying web code could power the callbacks on both Andorid and iOS devices.
I'm wondering if something like PhoneGap or Appcelerator provides a way to do this simply; however I don't need their core product (providing a native experience via underlying html/css/js) and I dont even know if what I need is included in their package.
Thanks for any info!
I would say that the best way would be to do it yourself, combining those two examples:
function nativeDoStuff() {
if (androidbridge != null {
androidbridge.doStuff();
}
else {
//construct url
window.location = "myiphonescheme://dostuff";
}
come to think of it, if you're feeling ambitious you could code up a quick javascript object to do it for you:
function NativeAppBridge () {
function runMethod(methodName, params) {
if (androidbridge != null {
// If the android bridge and the method you're trying to call exists,
// we'll just call the method directly:
if (androidbridge[methodName] != null) {
androidbridge[methodName].apply(this, params);
}
}
else {
// building the url is more complicated; best I can think
// of is something like this:
var url = "myiphonescheme://" + methodName;
if (params.length > 0) {
url += "?"
var i = 0;
for (param in params) {
url += "param" + i + "=" + param;
++i;
if (i < params.length) {
url += "&";
}
}
}
}
}
}
Using it would then be as simple as:
var bridge = new NativeAppBridge();
function onClick() {
bridge.runMethod("doStuff", null);
}
Be aware that I coded this off the top of my head and don't have time to test, at the moment - but I think it should work well enough, provided I didn't make any major mistakes
You can try the XWebView project if you plan to use WKWebView
You can use phonegap plugins to do it. They provide an excelent way to communicate between their webview and your native layer.
Here you can see how to create one!
And my personal opinion on the subject: I've been using phonegap for a while and if you are on webviews, I strongly suggest you to rethink the way you're doing stuff and move to a mobile web platform. You probably can save a lot of time.
The way I see it, the great disadvantage on using this is you are creating a webpage instead of a mobile app. You cant use native components and your app gets less responsive. As you are already on webviews, I believe you can only find benefits on these platforms.

Categories

Resources