I'm trying to use the node modules deasync and x11 to perform actions when certain keys are pressed.
When I use deasync inside a callback that has been initiated by a keypress deasync seems to be stuck in an endless loop.
It works fine if I create a generic event myself.
Run the following script using xtrace to see that X11 does respond:
xtrace -D :10 ./the-script
#!/usr/bin/env node
var deasync = require('deasync');
var x11 = require('x11');
var display = (deasync(x11.createClient)());
var client = display.client;
var getInputFocus = deasync(client.GetInputFocus)
.bind(client);
var focus1 = getInputFocus();
console.log("getting focus here works:", focus1);
// grab the "1"-key - keyCode = 10
client.GrabKey(display.screen[0].root, 0, null, 10, 0, 1);
client.on('event', processKeyPressEvent);
// client.emit("event"); // works
function processKeyPressEvent(event) {
console.log("can see this");
var focus2 = getInputFocus(); // problem
console.log("never get here");
}
Thanx for your help.
Related
I am trying to write a JXA script which extends the bounds the current window of the current application vertically so it reaches from the top to the bottom of the screen. If I run the following script in Automator as a "Run JavaScript" quick action, it works:
var app = Application.currentApplication();
var window = app.windows[0];
var orig_bounds = window.properties().bounds;
var vertical_res =
Application("Finder").desktop.window.properties().bounds.height;
window.bounds = {
"x": orig_bounds.x,
"y": 0,
"width": orig_bounds.width,
"height": vertical_res
};
I want this script to be bound to a hotkey. When I bind it in System Preferences -> Keyboard -> Shortcuts -> Services -> General and try to activate it while some app is active (say, iTerm 2), it doesn't work, and I get the error:
The action “Run JavaScript” encountered an error: “Error on line 4: TypeError: undefined is not an object (evaluating 'window.properties')”
Note that if I modify the script to always operate on a specific app (var app = Application("Google Chrome");) and run it in Automator, it works.
You need to get the application currently in use (the front most application), as the current application is the one running the Javascript code. This is why the code works when it's run in Automator and when a certain application is hard-coded.
To get the application in use you can use the two lines below:
var frontAppName = Application("System Events").processes.whose({frontmost: {'=': true }})[0].name();
var frontApp = Application(frontAppName);
I can't be certain about the error but I understand that it is generally considered good practice to include the Standard Definitions, and I've included it in the revised code below which doesn't cause this error when using a hot key combination.
function run(input, parameters) {
var app = Application.currentApplication();
app.includeStandardAdditions = true;
var frontAppName = Application("System Events").processes.whose({frontmost: {'=': true }})[0].name();
var frontApp = Application(frontAppName);
var window = frontApp.windows[0];
var orig_bounds = window.properties().bounds;
var vertical_res = Application("Finder").desktop.window.properties().bounds.height;
var orig_x = orig_bounds.x;
var orig_width = orig_bounds.width;
frontApp.windows[0].bounds = {
x: orig_x,
y: 0,
width: orig_width,
height: vertical_res
};
}
I am working on Protractor for testing the Angular JS application. I have written a code to read the data from excel sheet.My scenario is like I have a end to end flow that should execute.The code will take the URL,UserName and Password from the excel sheet and will execute the entire flow. Than again it will iterate the other value. But its not going into the loop.
My code is:
var Excel = require('exceljs');
var XLSX = require('xlsx');
var os = require('os');
var TEMP_DIR = os.tmpdir();
var wrkbook = new Excel.Workbook();
//---------------------Duration as Days------------------------------------------
describe('Open the clinicare website by logging into the site', function () {
it('IP Medication Simple flows for Patient Keerthi for Days,Weeks and Months', function () {
console.log("hello6");
browser.driver.manage().window().maximize();
var wb = XLSX.readFile('E:\\LAM WAH EE_Testing Enviornment\\IP_Medication_Flow\\Patients_Entry.xlsx');
var ws = wb.Sheets.Sheet1;
var json = XLSX.utils.sheet_to_json(wb.Sheets.Sheet1);
console.log("json", json);
//var json = XLSX.utils.sheet_to_json(wb.Sheets.Sheet1);
//console.log("json", json);
for(var a = 0; a < json.length ; a++){
console.log("Test_URL", json[a].Test_URL);
console.log("User_Name", json[a].User_Name);
console.log("Password", json[a].Password);
browser.get(json[a].Test_URL);
console.log("hello10");
//Perform Login:UserName
element(by.model('accessCode')).sendKeys(json[a].User_Name);
browser.sleep(6000);
// browser.driver.sleep(6000);
//Perform Login:Password
element(by.model('password')).sendKeys(json[a].Password);
browser.sleep(6000);
//Hospital Name
element(by.cssContainingText('option', 'HLWE')).click();
browser.sleep(6000);
//Perform Login:LoginButton
element(by.css('.btn.btn-primary.pull-right')).click();
browser.sleep(6000);
//Clicking on Admitted Tab
element(by.xpath("//span[contains(text(),' Admitted(25)')]")).click();
browser.sleep(6000);
// browser.driver.sleep(6000);
//Clicking on First Admitted Patient
element(by.cssContainingText('span.clearfloat', '35690')).element(by.xpath('//*[#id="searchPatientImgAdmittedF"]')).click();
jasmine.DEFAULT_TIMEOUT_INTERVAL = 600000;
// browser.sleep(600);
//Clicking anywhere to proceed
element(by.xpath('/html/body/div[3]/div[1]/div[16]/div[1]/div/table[4]/tbody/tr[2]/td/div/div/div[3]/table/tbody/tr[1]/td[3]')).click();
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
browser.sleep(800);
Anyone's help is appreciated. Thanks in advance.
Alright initially confused with the 'exceljs' node module. It is not used in your test. I think the major problem here is that the file does not exist.
readFile and ENOENT
The first thing of the readFile is an alias for readFileSync which calls readSync which calls (probably) read_binary which offloads to node's fs.readFileSync. More than likely the fs.readFileSync is throwing the ENOENT because the path does not exist.
Looking at your path, you might need a backslash before your spaces.
var wb = XLSX.readFile('E:\\LAM\ WAH\ EE_Testing Enviornment\\IP_Medication_Flow\\Patients_Entry.xlsx');
It could be a good practice to get the file path with path.resolve prior to calling the read file method.
var path = require('path');
var patientEntryFilePath = path.resolve('E:\\LAM\ WAH\ EE_Testing Enviornment\\IP_Medication_Flow\\Patients_Entry.xlsx');
console.log(patientEntryFilePath);
var wb = XLSX.readFile(patientEntryFilePath);
Additional comments and thoughts about the original code snippet
Some additional comments about the code snippet from the original question. Maybe considerations for future cleanup.
Think about using a beforeAll or beforeEach for setting your browser driver window size and reading in a file. Reading in the file once is potentially a time and resource saver.
describe('Open the clinicare website by logging into the site', function () {
var json = null;
beforeAll(() => {
browser.driver.manage().window().maximize();
var wb = XLSX.readFile('E:\\LAM\ WAH\ EE_Testing Enviornment\\IP_Medication_Flow\\Patients_Entry.xlsx');
var ws = wb.Sheets.Sheet1;
json = XLSX.utils.sheet_to_json(wb.Sheets.Sheet1);
});
it('IP Medication Simple flows for Patient Keerthi for Days,Weeks and Months', function () {
console.log("json", json);
...
Looking at your test that it is a login and it appears to have the same flow, you really only need to test this once. The for loop is acceptable since the json file is resolved and each line is executed in the control flow that Protractor uses.
Avoid using xpath. It is better to find elements by css or id or partial path. In the developer adds an additional div in the list of div's will break your test, making your test more fragile and require more upkeep.
This because Protractor API execute Async, but the For loop execute Sync. Get detail explain from here, which is same issue as yours.
To fix your issue, we can use javascript closure.
for(var a = 0; a < json.length ; a++) {
(function(a){
console.log("Test_URL", json[a].Test_URL);
console.log("User_Name", json[a].User_Name);
console.log("Password", json[a].Password);
browser.get(json[a].Test_URL);
console.log("hello10");
//Perform Login:UserName
element(by.model('accessCode')).sendKeys(json[a].User_Name);
browser.sleep(6000);
// browser.driver.sleep(6000);
//Perform Login:Password
element(by.model('password')).sendKeys(json[a].Password);
browser.sleep(6000);
...
})(a)
}
I am working on a Raspberry3 model B.
I've written a code that I want to launch on reboot.
If I launch the script in the bash it works perfectly. But when I try to start the script via doubleclick (execute in terminal) it opens the terminal for a very short duration and closes it immediatly after.
Same thing happens if I want to start this script at reboot.
Can anyone tell me what I'm doing wrong?
var blynkLib = require('blynk-
library');
var sensorLib = require('node-dht-
sensor');
var AUTH = 'xxx';
// Setup Blynk
var blynk = new
blynkLib.Blynk(AUTH);
// Setup sensor, exit if failed
var sensorType = 22; // 11 for DHT11, 22 for DHT22 and AM2302
var sensorPin = 2; // The GPIO pin number for sensor signal
if
(!sensorLib.initialize(sensorType,
sensorPin)) {
console.warn('Failed to
initialize sensor');
process.exit(1);
}
// Automatically update sensor value every 2 seconds
setInterval(function() {
var readout = sensorLib.read();
blynk.virtualWrite(3,
readout.temperature.toFixed(1));
blynk.virtualWrite(4,
readout.humidity.toFixed(1));
console.log('Temperature:',
readout.temperature.toFixed(1) +
'C');
console.log('Humidity: ',
readout.humidity.toFixed(1) +
'%');
}, 2000);
Assuming your question is How can i pause my program :
using python : you should import os then os.system("pause"); :
import os;
os.system("pause");
Using nodejs : use one of the module from npm :
https://www.npmjs.com/package/system-sleep
https://www.npmjs.com/package/pause
I am trying to run a command from gjs and read the output asynchronously.
here is my synchronous code
let [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null,
['/bin/ls'], null, 0, null);
let out_reader = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({fd: out_fd})
});
var out = out_reader.read_until("", null);
print(out);
this works fine but if I try to do it asynchronously it doesn't work
let [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null,
['/bin/ls'], null, 0, null);
let out_reader = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({fd: out_fd})
});
function _SocketRead(source_object, res, user_data){
print("hi");
let length;
let out = out_reader.read_upto_finish(asyncResult, length);
print("out" + out);
print("length" + length);
}
var out = out_reader.read_upto_async("",0, 0, null, _SocketRead, "");
while(true){
i = 0;
}
the callback is not called at all
First of all thank you for the question, I also had the same underlying question, that is, your initial line "I am trying to run a command from gjs and read the output asynchronously" and your question had the details I needed to find the solution!
In your example code, the major problem is these lines:
while(true){
i = 0;
}
You are correctly trying to keep the program from terminating before you get the output, but this solution doesn't work.
Javascript is single threaded, meaning that while computations can run concurrently in the serial interleaved sense, there can't be two Javascript computations running in parallel. There is no way to explicitly yield the thread and the busy loop in the question just keeps on spinning and the callback never gets CPU time.
What you want instead is to enter an event loop. If you are developing a Gnome Shell extension, you are already running in one, but if you are just running a script with Gjs, you need to explicitly start one. I'm going to use Clutter, but some other event loop will do just as well. The following code segments constitute a full, working solution.
First of all, let's start by importing needed libraries:
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Clutter = imports.gi.Clutter;
Then add the spawning and file descriptor from the question:
const [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null, ['/bin/ls'], null, 0, null);
const out_reader = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({fd: out_fd})
});
Call the async reading function and give it a callback (defined below, usable here thanks to Javascript hoisting):
out_reader.read_upto_async("", 0, 0, null, _SocketRead, "");
And start the event loop:
Clutter.init(null);
Clutter.main();
There were a couple of errors in your callback, so here a fixed version that also terminates the event loop once the command stops producing output:
function _SocketRead(source_object, res){
const [out, length] = out_reader.read_upto_finish(res);
if (length > 0) {
print("out: " + out);
print("length: " + length);
out_reader.read_upto_async("", 0, 0, null, _SocketRead, "");
} else {
Clutter.main_quit();
}
}
For further reading there are Gjs native bindings docs at https://gjs-docs.gnome.org/.
I am looking for a way of getting the process memory of any process running.
I am doing a web application. I have a server (through Nodejs), my file app.js, and an agent sending information to app.js through the server.
I would like to find a way to get the process memory of any process (in order to then sending this information to the agent) ?
Do you have any idea how I can do this ? I have searched on google but I haven't found my answer :/
Thank you
PS : I need a windows compatible solution :)
Windows
For windows, use tasklist instead of ps
In the example below, i use the ps unix program, so it's not windows compatible.
Here, the %MEM is the 4st element of each finalProcess iterations.
On Windows the %MEM is the 5th element.
var myFunction = function(processList) {
// here, your code
};
var parseProcess = function(err, process, stderr) {
var process = (process.split("\n")),
finalProcess = [];
// 1st line is a tab descriptor
// if Windows, i should start to 2
for (var i = 1; i < process.length; i++) {
finalProcess.push(cleanArray(process[i].split(" ")));
}
console.log(finalProcess);
// callback to another function
myFunction(finalProcess);
};
var getProcessList = function() {
var exec = require('child_process').exec;
exec('ps aux', parseProcess.bind(this));
}
// thx http://stackoverflow.com/questions/281264/remove-empty-elements-from-an-array-in-javascript
function cleanArray(actual){
var newArray = new Array();
for(var i = 0; i<actual.length; i++){
if (actual[i]){
newArray.push(actual[i]);
}
}
return newArray;
}
getProcessList();