I'm trying to get the following working based on this post "Building a CapacitorJS application using pure JavaScript and Webpack" on Medium.com (https://medium.com/#SmileFX/a-complete-guide-building-a-capacitorjs-application-using-pure-javascript-and-webpack-37d00f11720d)
My intention is to build an Android app that will get deployed from an MDM server with an AppConfig configuration. When launched, the app will generate a file (derived from the AppConfig configuration) and save the file to the file system on the device.
Here is the content of my index.js
import '#capacitor/core';
import '#angular/core';
import '#ionic-native/core';
import 'rxjs';
import { Device } from '#capacitor/device';
import { Filesystem, Directory, Encoding } from '#capacitor/filesystem';
//import { EmmAppConfig } from '#ionic-native/emm-app-config/ngx';
async function getDeviceInfo() {
message("getDeviceInfo started");
let info = await Device.getInfo();
return info.operatingSystem;
}
async function getEmmAppConfig() {
message("getEmmAppConfig started");
//let eac = await EmmAppConfig.getValue("z_number");
let eac = "Z_1234_567";
return eac;
};
async function putFile(name, data) {
message("putFile started with name: " +name+ " and data: " +data);
let file = await Filesystem.writeFile({
path: "file:///storage/emulated/0/z_number/" +name+ ".txt",
data: data,
recursive: true,
encoding: Encoding.UTF8
});
return file;
};
window.onload = start;
function start() {
message("app started");
getDeviceInfo().then(info => {
putFile("info", info).then(file => {
message("File saved here: " +JSON.stringify(file, null, 4));
});
});
getEmmAppConfig().then(eac => {
putFile("eac", eac).then(file => {
message("File saved here: " +JSON.stringify(file, null, 4));
});
});
}
function message(message) {
document.body.innerHTML = document.body.innerHTML+ "<p>" +message+ "</p>" ;
}
The above code does run on the Android emulator and saves bothe files as expected only when "import { EmmAppConfig } from '#ionic-native/emm-app-config/ngx';" is commented out, otherwise it does not run (not even to output "App Started")
this is the content of my package.json
{
"name": "capacitor-app",
"version": "1.0.0",
"description": "An Amazing Capacitor App",
"main": "index.js",
"keywords": [
"capacitor",
"mobile"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"#angular/core": "^13.0.3",
"#capacitor/android": "^3.3.2",
"#capacitor/camera": "latest",
"#capacitor/core": "latest",
"#capacitor/device": "^1.1.0",
"#capacitor/filesystem": "^1.0.6",
"#capacitor/splash-screen": "latest",
"#ionic-native/core": "^5.36.0",
"#ionic-native/emm-app-config": "^5.36.0",
"cordova-plugin-emm-app-config": "^1.0.2",
"rxjs": "^7.4.0"
},
"devDependencies": {
"#capacitor/cli": "latest",
"webpack-cli": "^4.9.1"
},
"author": "",
"license": "ISC"
}
What am i missing?
Related
I installed "npm install axios" and imported using "import axios from 'axios'.
I wanted to post the data and get the data
These are the codes I have used.
Package.json :
{
"name": "ceniplex-tickets",
"version": "1.0.0",
"description": "ticket booking app",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Aswin Anilkumar",
"license": "ISC",
"devDependencies": {
"parcel": "^2.8.1",
"parcel-bundler": "^1.8.1"
},
"dependencies": {
"axios": "^1.2.1"
}
}
JS code (Front end) :
import axios from 'axios';
class Model {
constructor() {
this.array = []
}
getArray() {
return this.array;
}
async loadTicketsFromBackend() {
const req = await axios.get('http://localhost:3000/booking')
const booking = req.data;
console.log(booking);
}
async setArray(data) {
const res = await axios.post('http://localhost:3000/booking',data)
return res;
}
}
export default Model;
My electron app is using the remote isolation approach (mentioned in this article). My remote web app is a Ruby on Rails app. Now, I want to push notifications from a remote web app to the electron app using WebSocket. To send the message to users even if they shut off the app, I got an idea. In the Rails server, I use ActionCable to broadcast the notifications to a channel. In the main process, I subscribe to this channel by using the actioncable package.
import ActionCable from "actioncable";
const websocketUrl = "wss://rt.custom-domain.dev/_/cable";
const cable = ActionCable.createConsumer(websocketUrl);
cable.subscriptions.create(
{ channel: "WallChannel", wall_id: "106" },
{
received(data: any): void {},
disconnect(): void {},
connected(): void {},
disconnected(): void {},
present(): void {},
absent(): void {},
}
);
But I got an error:
ReferenceError: window is not defined
Then I dive deep into the source code of the actioncable package and I found that the package using WebSocket API of the browser so that why the error appeared.
I tried to use ws package to subscribe to the websocket instead by following this post. But I couldn't connect to the websocket server. When I call App.ws.sendmessage I got an error:
Error: WebSocket is not open: readyState 0 (CONNECTING)
Has anyone tried to push notifications from the remote web app by using websocket like what I've trying? Did you got the same problem? or If you got a better solution for my case, please share with me your idea. Thanks a lot.
This is my main.ts file of the electron app
import { app, BrowserWindow, ipcMain, Notification } from "electron";
import { createWindow } from "src/main/CreateWindow";
import { showNotification } from "./helpers";
import appConfigs from "src/AppConfigs";
let mainWindow: BrowserWindow;
const createAppWindow = () => {
mainWindow = createWindow(appConfigs.targetUrl, { interop: true });
// Open the DevTools.
if (!app.isPackaged) {
mainWindow.webContents.openDevTools();
}
};
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require("electron-squirrel-startup")) {
// eslint-disable-line global-require
app.quit();
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on("ready", () => {
createAppWindow();
});
var App: { ws: any; param: any; connect_server: any; sendmessage: any } = {
ws: null,
param: null,
connect_server: () => {},
sendmessage: () => {},
};
App.sendmessage = function (send: any) {
let data = {
message: send,
action: "speak",
};
let message = {
command: "message",
identifier: JSON.stringify(App.param),
data: JSON.stringify(data),
};
App.ws.send(JSON.stringify(message));
};
App.connect_server = function () {
const WebSocket = require("ws");
App.ws = new WebSocket("wss://rt.custom-domain.dev/_/cable", [
"actioncable-v1-json",
"actioncable-unsupported",
]);
console.log("connect_server", App.ws);
App.param = { channel: "WallChannel", wall_id: 106 };
App.ws.on("open", function open() {
console.log("open channel");
let data = {
command: "subscribe",
identifier: JSON.stringify(App.param),
};
App.ws.send(JSON.stringify(data));
console.log("send JSON");
});
App.ws.on("message", function (event: any) {
console.log("message", event);
});
App.ws.on("error", function (err) {
console.log("Found error: " + err);
});
};
App.connect_server();
CreateWindow.ts
import { BrowserWindow } from "electron";
import appConfigs from "src/AppConfigs";
declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY: any;
interface BrowserWindowOption {
title?: string;
height?: string;
width?: string;
interop?: boolean;
}
export const createWindow = (
url: string,
options: BrowserWindowOption = {}
): BrowserWindow => {
// Create the browser window.
const mainWindow = new BrowserWindow({
title: options.title || appConfigs.name,
height: options.height || appConfigs.height,
width: options.width || appConfigs.width,
webPreferences: options.interop
? {
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
}
: {},
});
// and load the targetUrl.
mainWindow.loadURL(url || appConfigs.targetUrl);
return mainWindow;
};
package.json
{
"name": "electron-forge-app",
"productName": "electron-forge-app",
"version": "1",
"description": "My Electron application description",
"main": ".webpack/main",
"scripts": {
"start": "electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make",
"publish": "electron-forge publish",
"lint": "eslint --ext .ts ."
},
"keywords": [],
"author": {
...
},
"license": "MIT",
"config": {
"forge": {
"packagerConfig": {},
"makers": [
{
"name": "#electron-forge/maker-squirrel",
"config": {
"name": "electron_furge"
}
},
{
"name": "#electron-forge/maker-zip",
"platforms": [
"darwin"
]
},
{
"name": "#electron-forge/maker-deb",
"config": {}
},
{
"name": "#electron-forge/maker-rpm",
"config": {}
}
],
"plugins": [
[
"#electron-forge/plugin-webpack",
{
"mainConfig": "./webpack.main.config.js",
"renderer": {
"config": "./webpack.renderer.config.js",
"entryPoints": [
{
"html": "./src/index.html",
"js": "./src/renderer.ts",
"name": "main_window",
"preload": {
"js": "./src/interop/preload.ts"
}
}
]
}
}
]
]
}
},
"devDependencies": {
"#electron-forge/cli": "^6.0.0-beta.54",
"#electron-forge/maker-deb": "^6.0.0-beta.54",
"#electron-forge/maker-rpm": "^6.0.0-beta.54",
"#electron-forge/maker-squirrel": "^6.0.0-beta.54",
"#electron-forge/maker-zip": "^6.0.0-beta.54",
"#electron-forge/plugin-webpack": "6.0.0-beta.54",
"#marshallofsound/webpack-asset-relocator-loader": "^0.5.0",
"#types/actioncable": "^5.2.4",
"#typescript-eslint/eslint-plugin": "^4.0.1",
"#typescript-eslint/parser": "^4.0.1",
"css-loader": "^4.2.1",
"electron": "12.0.5",
"eslint": "^7.6.0",
"eslint-plugin-import": "^2.20.0",
"fork-ts-checker-webpack-plugin": "^5.0.14",
"node-loader": "^1.0.1",
"style-loader": "^1.2.1",
"ts-loader": "^8.0.2",
"typescript": "^4.0.2"
},
"dependencies": {
"actioncable": "^5.2.6",
"electron-squirrel-startup": "^1.0.0",
"ws": "^7.4.5"
}
}
Im creating an NFL football simulator in nodejs and am having trouble exporting one of my variables. As you can see in my get_teams.js i make many HTTP requests. I then process the responseArr and format the data. Where I am running into an issue is when I try and export the sorted_teams_array. you can find this code at the very bottom of get_teams.js.
I then try and import this array into tester.js and console log it. I will eventually use this file to inject a mongo database with the array, but for now am just trying to console log it and cannot get it to work. I am using the --experimental-modules in my npm scripts when I run npm run tester, and still nothing. Any help would be great! I am a noobie so please no hate!
get_teams.js
import axios from 'axios';
import Nfl_team from '../models/teamModel.js';
import Offensive_stats from '../models/offensiveStatsModel.js';
import Defensive_stats from '../models/defensiveStatsModel.js';
import Game_stats from '../models/gameStatsModel.js';
import colors from 'colors';
import dotenv from 'dotenv';
dotenv.config();
const teams = {};
function get_teams() {
axios.all([
axios.get(`https://api.sportsdata.io/api/nfl/fantasy/json/Standings/${process.env.SEASON}?key=${process.env.API_KEY}`),
// ... many more gets
])
.then(function (responseArr) {
responseArr[0].data.forEach(element => {
teams[element.Team] = new Nfl_team(element.Team, element.Name, element.Wins, element.Losses, element.Ties,
element.Percentage, element.DivisionWins, element.DivisionLosses, element.DivisionTies,
element.PointsFor, element.PointsAgainst)
});
// many more forEach blocks on responseArr[1, 2, 3...]
/* power rating algorithm logic
_____________________________________________ */
const teams_array = Object.entries(teams);
export const sorted_teams_array = teams_array.sort((a, b) => {
if (a[1].average_victory_margin > b[1].average_victory_margin) return -1;
if (a[1].average_victory_margin < b[1].average_victory_margin) return 1;
return 0;
})
console.log(sorted_teams_array);
teams_array.forEach(element => {
console.log(`average victory margin for ${element[0]} = ${element[1].average_victory_margin}`)
});
})
.catch(function (error) {
// handle error
console.log(error);
})
}
get_teams();
tester.js
import { sorted_teams_array } from './get_teams';
console.log(sorted_teams_array);
/// returns
(node:58769) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/resolve.js:61
let url = moduleWrapResolve(specifier, parentURL);
^
Error: Cannot find module /Users/jojovera/Documents/nflSIMULATION/teams/get_teams imported from /Users/jojovera/Documents/nflSIMULATION/teams/tester.js
at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:61:13)
at Loader.resolve (internal/modules/esm/loader.js:94:40)
at Loader.getModuleJob (internal/modules/esm/loader.js:240:28)
at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:42:40)
at link (internal/modules/esm/module_job.js:41:36) {
code: 'ERR_MODULE_NOT_FOUND'
}
package.json
{
"name": "optionsscript",
"version": "1.0.0",
"description": "",
"main": "app.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node --experimental-modules app.js",
"afc_west": "node --experimental-modules ../nflSIMULATION/teams/afc_west.js",
"get_teams": "node --experimental-modules ../nflSIMULATION/teams/get_teams.js",
"tester": "node --experimental-modules ../nflSIMULATION/teams/tester.js",
"get_offensive_stats": "node --experimental-modules ../nflSIMULATION/teams/get_offensive_stats.js",
"get_defensive_stats": "node --experimental-modules ../nflSIMULATION/teams/get_defensive_stats.js",
"get_victory_margin": "node --experimental-modules ../nflSIMULATION/teams/get_victory_margin.js",
"power_rank": "node --experimental-modules ../nflSIMULATION/teams/power_rank.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.21.0",
"cheerio": "^1.0.0-rc.5",
"colors": "^1.4.0",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"nodemon": "^2.0.6",
"stats-lite": "^2.2.0",
"terminal-kit": "^1.44.0",
"tofixed": "^1.0.0"
}
}
As addressed in the comments and chat, there were two issues: ESM isn't supported in Node 12, so an update to 15 fixed that. The other issue is that nothing was validly exported from get_teams: import and export are top-level keywords, and the export was taking place inside a .then. These minor changes allow the function to be imported and its result used in the tests:
export function get_teams() {
return axios.all([
/// rest of code
return sorted_teams_array;
})
.catch(function (error) {
// handle error
console.log(error);
})
}
Usage example:
import { get_teams } from './get_teams'
get_teams.then((teams) => {
teams.forEach(console.log)
})
I am trying to locate the element using Javascript, appium, WebdriverIo and Mocha. The app is getting launch on emulator but getting error while locating element.Any other approach that can be used?
The testclass.js file code is given below:
const wdio = require("webdriverio");
//example capabilities
const opts = {
port: 4723,
capabilities: {
platformName: "Android",
deviceName: "emulator-5554",
app: "D:demo.apk",
appPackage: "com.somepackage",
appActivity: "com.somepackage.acivity",
newCommandTimeout: 500,
noReset: "true",
automationName: "UiAutomator2"
}
};
var client = wdio.remote(opts);
describe('Test App launch', function () {
this.timeout(15000);
it('register', async function(){
// This is the error line below
**const elm = await client.findElement("resource-id","goRegistrationButton")**
elm.click();
});
});
package.json file:
{
"name": "testclass",
"version": "1.0.0",
"description": "Automating app",
"main": "testclass.js",
"scripts": {
"test": "testclass.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"mocha": "^6.0.2",
"typescript": "^3.3.4000",
"webdriverio": "^5.7.6"
},
"devDependencies": {
"ts-node": "^8.0.3"
}
}
I am expecting to click the element for the native android app using javascript and webdriverIO
I want to test a ng-redux reducer wich have angular (1.6) as dependency.
When I run the tests (npm test) with mocha, I get :
/data/work/mocha-angularjs/node_modules/angular/angular.js:33343
})(window);
^
ReferenceError: window is not defined
I tried to add jsdom to provide a fake window. But it still fails during the import of angular with this error :
module.exports = angular;
^
ReferenceError: angular is not defined
Is there a way to make angular work properly in mocha/babel world ?
I made a small github project available here which reproduce the problem.
Here is the content of the project :
Package.json
{
"name": "mocha-angularjs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"angular": "^1.6.3"
},
"devDependencies": {
"babel-core": "^6.24.0",
"babel-preset-es2015": "^6.24.0",
"babel-preset-latest": "^6.24.0",
"chai": "^3.5.0",
"jsdom": "9.12.0",
"jsdom-global": "2.1.1",
"mocha": "^3.2.0"
},
"scripts": {
"test": "NODE_ENV=test mocha src/index.test.js --compilers js:babel-register --require jsdom-global/register"
},
"repository": {
"type": "git",
"url": "git+https://github.com/jtassin/mocha-angularjs.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/jtassin/mocha-angularjs/issues"
},
"homepage": "https://github.com/jtassin/mocha-angularjs#readme"
}
.babelrc
{
"plugins": [],
"presets": [
"latest",
]
}
The code to test
import angular from 'angular';
export default function getFive() {
return 5;
}
The test
import expect from 'chai';
import getFive from './index';
describe('desc', () => {
it('my test', () => {
expect(getFive()).to.equal(5);
});
});
In case of someone needs it one day :
I used angularcontext to solve the problem.
package.json
"devDependencies": {
"angularcontext": "0.0.23",
[...]
},
In my test file
/* eslint-env mocha */
/* eslint-disable import/no-extraneous-dependencies */
import angularcontext from 'angularcontext';
before((done) => {
const context = angularcontext.Context();
context.runFile('./node_modules/angular/angular.js', (result, error) => {
if (error) {
/* eslint-disable no-console */
console.error(error);
done(error);
} else {
global.angular = context.getAngular();
done();
}
});
});
/* eslint-disable import/prefer-default-export */
export const angular = global.angular;
The github project has been updated with it.