use .net dll in electron - javascript

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.

Related

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.

Accessing local files in offline jquery app

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

How to use PhantomJS along with node.js for scraping?

I have installed node-phantom by npm install node-phantom but when I am running this code, it is giving Cannot find module 'webpage' this error
var webpage = require('webpage').create(),
url = "https://www.example.com/cba/abc",
hrefs = new Array();
webpage.open(url,function(status){
if(status=="success"){
var results = page.evaluate(function(){
$("#endpoints").each(function() {
hrefs.push($(this).attr("href"));
});
return hrefs;
});
console.log(JSON.stringify(results));
phantom.exit();
}
});
You don't require the webpage module in node-phantom. You would use its API to get a representation of the webpage module. It has to be done this way, because PhantomJS has a different execution runtime from node.js. They generally can't use the same modules. That is why there are bridges between those two execution environments like node-phantom and phantom. They essentially replicate the API of PhantomJS to be used in node.js.
As per documentation, you don't require the webpage, you get a page instead:
var phantom = require('node-phantom');
phantom.create(function(err,ph) {
return ph.createPage(function(err,page) {
// do something with page: basically your script
});
});
You won't be able to just copy and paste existing PhantomJS code. There are differences, so you will have to study the API (basically the README on github).
Complete translation of your code:
var phantom = require('node-phantom');
phantom.create(function(err,ph) {
return ph.createPage(function(err,page) {
page.open(url,function(status){
if(status=="success"){
page.evaluate(function(){
hrefs = [];
$("#endpoints").each(function() {
hrefs.push($(this).attr("href"));
});
return hrefs;
}, function(err, results){
console.log(JSON.stringify(results));
ph.exit();
});
}
});
});
});
page.evaluate is still sandboxed, so you can't use variables from the outside like hrefs.

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

Detect between a mobile browser or a PhoneGap application

Is it possible to detect if the user is accessing through the browser or application using JavaScript?
I'm developing a hybrid application to several mobile OS through a web page and a PhoneGap application and the goal would be to:
Use the same code independently of the deployment target
Add PhoneGap.js file only when the user agent is an application
You could check if the current URL contains http protocol.
var app = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1;
if ( app ) {
// PhoneGap application
} else {
// Web page
}
Quick solution comes to mind is,
onDeviceReady
shall help you. As this JS call is invoked only by the Native bridge (objC or Java), the safari mobile browser will fail to detect this. So your on device app(phone gap) source base will initiate from onDeviceReady.
And if any of the Phonegap's JS calls like Device.platform or Device.name is NaN or null then its obviously a mobile web call.
Please check and let me know the results.
I figured out a way to do this and not rely on deviceready events thus, keeping the web codebase intact...
The current problem with using the built in deviceready event, is that when the page is loaded, you have no way of telling the app: "Hey this is NOT running on an mobile device, there's no need to wait for the device to be ready to start".
1.- In the native portion of the code, for example for iOS, in MainViewController.m there's a method viewDidLoad, I am sending a javascript variable that I later check for in the web code, if that variable is around, I will wait to start the code for my page until everything is ready (for example, navigator geolocation)
Under MainViewController.m:
- (void) viewDidLoad
{
[super viewDidLoad];
NSString* jsString = [NSString stringWithFormat:#"isAppNative = true;"];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
2.- index.html the code goes like this:
function onBodyLoad()
{
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady(){;
myApp.run();
}
try{
if(isAppNative!=undefined);
}catch(err){
$(document).ready(function(){
myApp.run();
});
}
PhoneGap has window.PhoneGap (or in Cordova, it's window.cordova or window.Cordova) object set. Check whether that object exists and do the magic.
Inside the native call where the url for the phonegap app is loaded you add a parameter target with value phonegap. So the call for android becomes something like this.
super.loadUrl("file:///android_asset/www/index.html?target=phonegap");
Your website using this code won't be called with the extra parameter, so we now have something different between the two deploying platforms.
Inside the javascript we check if the parameter exists and if so we add the script tag for phonegap/cordova.
var urlVars = window.location.href.split('?');
if(urlVars.length > 1 && urlVars[1].search('target=phonegap') != -1){
//phonegap was used for the call
$('head').append('<script src="cordova.js"></script>');
}
A small caveat: this method requires to change the call to index.html in phonegap for each different targeted mobile platform. I am unfamiliar where to do this for most platforms.
what if you try following :
if(window._cordovaNative) {
alert("loading cordova");
requirejs(["...path/to/cordova.js"], function () {
alert("Finished loading cordova");
});
}
I am using the same code for both phonegap app and our web client. Here is the code that I use to detect if phonegap is available:
window.phonegap = false;
$.getScript("cordova-1.7.0.js", function(){
window.phonegap = true;
});
Keep in mind that phonegap js file is loaded asynchronously. You can load it synchronously by setting the correct option of a nifty jquery $.getScript function.
Note that approach does make an extra GET request to grab phonegap js file even in your webclient. In my case, it did not affect the performance of my webclient; so it ended up being a nice/clean way to do this.Well at least until someone else finds a quick one-line solution :)
It sounds like you are loading another webpage once the webview starts in the Phonegap app, is that correct? If that's true then you could add a param to the request url based on configuration.
For example, assuming PHP,
App.Config = {
target: "phonegap"
};
<body onload="onbodyload()">
var onbodyload = function () {
var target = App.Config.target;
document.location = "/home?target=" + target;
};
Then on the server side, include the phonegap js if the target is phonegap.
There is no way to detect the difference using the user agent.
The way I'm doing it with is using a global variable that is overwritten by a browser-only version of cordova.js. In your main html file (usually index.html) I have the following scripts that are order-dependent:
<script>
var __cordovaRunningOnBrowser__ = false
</script>
<script src="cordova.js"></script> <!-- must be included after __cordovaRunningOnBrowser__ is initialized -->
<script src="index.js"></script> <!-- must be included after cordova.js so that __cordovaRunningOnBrowser__ is set correctly -->
And inside cordova.js I have simply:
__cordovaRunningOnBrowser__ = true
When building for a mobile device, the cordova.js will not be used (and instead the platform-specific cordova.js file will be used), so this method has the benefit of being 100% correct regardless of protocols, userAgents, or library variables (which may change). There may be other things I should include in cordova.js, but I don't know what they are yet.
Ive ben struggling with this aswell, and i know this is an old thread, but i havent seen my approach anywhere, so thought id share incase itll help someone.
i set a custom useragent after the actual useragent :
String useragent = settings.getUserAgentString();
settings.setUserAgentString(useragent + ";phonegap");
that just adds the phonegap string so other sites relying on detecting your mobile useragent still works.
Then you can load phonegap like this:
if( /phonegap/i.test(navigator.userAgent) )
{
//you are on a phonegap app, $getScript etc
} else {
alert("not phonegap");
}
To my mind you try to make issue for self. You didn't mentioned your development platform but most of them have different deployment configuration. You can define two configurations. And set variable that indicates in which way code was deployed.
In this case you don't need to care about devices where you deployed your app.
Short and effective:
if (document.location.protocol == 'file:') { //Phonegap is present }
Similar to B T's solution, but simpler:
I have an empty cordova.js in my www folder, which gets overwritten by Cordova when building. Don't forget to include cordova.js before your app script file (it took my one hour to find out that I had them in wrong order...).
You can then check for the Cordova object:
document.addEventListener('DOMContentLoaded', function(){
if (window.Cordova) {
document.addEventListener('DeviceReady', bootstrap);
} else {
bootstrap();
}
});
function bootstrap() {
do_something()
}
New solution:
var isPhoneGapWebView = location.href.match(/^file:/); // returns true for PhoneGap app
Old solution:
Use jQuery, run like this
$(document).ready(function(){
alert(window.innerHeight);
});
Take iPhone as example for your mobile application,
When using PhoneGap or Cordova, you'll get 460px of WebView, but in safari, you'll lose some height because of browser's default header and footer.
If window.innerHeight is equal to 460, you can load phonegap.js, and call onDeviceReady function
Nobody mentioned this yet, but it seems Cordova now supports adding the browser as a platform:
cordova platforms add browser
This will automatically add cordova.js during run-time, which features the onDeviceReady event, so that you do not need to fake it. Also, many plugins have browser support, so no more browser hacks in your code.
To use your app in the browser, you should use cordova run browser. If you want to deploy it, you can do so using the same commands as the other platforms.
EDIT: forgot to mention my source.
Solution: Patch index.html in Cordova and add cordova-platform="android" to <html> tag, so that cordova-platform attribute will be only present in Cordova build and missing from original index.html used for web outside of Cordova.
Pros: Not rely on user agent, url schema or cordova API. Does not need to wait for deviceready event. Can be extended in various ways, for example cordova-platform="browser" may be included or not, in order to distinguish between web app outside of Cordova with Cordova's browser platform build.
Merge with config.xml
<platform name="android">
<hook src="scripts/patch-android-index.js" type="after_prepare" />
</platform>
Add file scripts/patch-android-index.js
module.exports = function(ctx) {
var fs = ctx.requireCordovaModule('fs');
var path = ctx.requireCordovaModule('path');
var platformRoot = path.join(ctx.opts.projectRoot, 'platforms/android');
var indexPath = platformRoot + '/app/src/main/assets/www/index.html';
var indexSource = fs.readFileSync(indexPath, 'utf-8');
indexSource = indexSource.replace('<html', '<html cordova-platform="android"');
fs.writeFileSync(indexPath, indexSource, 'utf-8');
}
Notes: For other than android, the paths platforms/android and /app/src/main/assets/www/index.html should be adjusted.
App can check for cordova-platform with
if (! document.documentElement.getAttribute('cordova-platform')) {
// Not in Cordova
}
or
if (document.documentElement.getAttribute('cordova-platform') === 'android') {
// Cordova, Android
}

Categories

Resources