Hope you all had a wonderful holiday. My name is James David Bohrman and I am currently undertaking my first big code project that is not attached to a tutorial, so I'm exiting a huge stage in my journey.
My project is an Alexa skill that calls on the Cannabis Reports API by using an API wrapper called the same. The goal is to have a skill that accesses the API using the wrapper and creates a voice skill, but I'm having trouble with the Lambda.
Now I will state that I was testing in the Lambda console and not locally, which someone suggested I acquire tools to do.
As I said this is my first solo project so while I do not want my hand held, it is very important to my confidence that I finish this.
One of the errors I'm throwing in Bespoken CLI is "Cannot find module 'alexa-sdk'"
I have my package.json up to date on all my local versions of the project, even those not on GitHub, and alexa-sdk is for sure installed.
The github page is a little messy, but it's at https://github.com/jdbohrman/cannabis-reports-alexa
'use strict';
const Alexa = require('alexa-sdk');
var CannabisReport = require('cannabis-report');
const SKILL_NAME = 'Cannabis Report';
const answer = {
'AMAZON.HelpIntent': function () {
this.response.speak(HELP_MESSAGE).listen(HELP_REPROMPT);
this.emit(':responseReady');
},
'AMAZON.CancelIntent': function () {
this.response.speak(STOP_MESSAGE);
this.emit(':responseReady');
},
'AMAZON.StopIntent': function () {
this.response.speak(STOP_MESSAGE);
this.emit(':responseReady');
},
'CannabisReport': function () {
var speechOutput = Strain.search('');
this.emit ('tell', speechOutput);
}
};
exports.handler = function (event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.appId = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
});
Related
TL;DR: If I try to do var pty = require('node-pty'); results in TypeError: Object.setPrototypeOf: expected an object or null, got undefined keep reading for context
Hi, I'm trying to build a proof of concept by creating a terminal using React. For that, I used xterm-for-react which I made it work fine, and node-pty with this last library is with the one I'm having problems.
Initially I created a file in which I would try to make calls to it, it looks like this:
var os = require('os');
var pty = require('node-pty');
var shell = os.platform() === 'win32' ? 'powershell.exe' : 'bash';
var ptyProcess;
function createNewTerminal(FE){
ptyProcess = pty.spawn(shell, [], {
name: 'xterm-color',
cols: 80,
rows: 30,
cwd: process.env.HOME,
env: process.env
});
ptyProcess.onData((data) => FE.write(data));
}
function writeOnTerminal(data){
ptyProcess.write(data);
}
module.exports = {
createNewTerminal,
writeOnTerminal
}
I know it may not be the best code out there, but I was doing it just to try to see if this was possible. My plan was to call the functions from the react component like this:
import {createNewTerminal, writeOnTerminal} from './terminal-backend';
function BashTerminal() {
const xtermRef = React.useRef(null)
React.useEffect(() => {
// You can call any method in XTerm.js by using 'xterm xtermRef.current.terminal.[What you want to call]
xtermRef.current.terminal.writeln("Hello, World!")
createNewTerminal(xtermRef.current.terminal)
}, [])
const onData = (data) => {
writeOnTerminal(data);
}
return (
<XTerm ref={xtermRef} onData={onData}/>
);
}
But I was surprised that this was not working, and returned the error in the title. So, in order to reduce noise, I tried to change my functions to just console logs and just stay with the requires. My file now looked like this:
var os = require('os');
var pty = require('node-pty');
function createNewTerminal(FE){
console.log("Creating new console");
}
function writeOnTerminal(data){
console.log("Writing in terminal");
}
module.exports = {
createNewTerminal,
writeOnTerminal
}
Still got the same error. I'm currently not sure if this is even possible to do, or why this error occurs. Trying to look things online doesn't give any results, or maybe it does and I'm just not doing it right. Well, thanks for reading, I'm completely lost, so, if someone knows something even if it's not the complete answer I will be very thankful
I have an instability issue.
I'm using openzeppelin-test-helpers, and first had an issue with typescript saying Could not find a declaration file for module '#openzeppelin/test-helpers'.. This issue was solved by creating a .d.ts file containing declare module "#openzeppelin/test-helpers";.
However, adding this created a new problem, which is that now, most of the time, only one file is being run by rm -rf build && truffle test (I guess this is similar to truffle test --reset).
I got 2 test files. The first one looks like:
require("chai")
.use(require("chai-as-promised"))
.should();
const EventHandler = artifacts.require("EventHandler");
const { expectRevert } = require("#openzeppelin/test-helpers");
contract("EventHandler", function([_, superAdmin0, admin0, device0]) {
beforeEach(async function() {
this.eventHandler = await EventHandler.new(superAdmin0);
});
describe("Initial tests", function() {
it("should print hello", async function() {
await this.eventHandler
.printHello()
.should.eventually.equal("Hello");
});
});
});
The second one looks like:
require("chai")
.use(require("chai-as-promised"))
.should();
const { expectRevert } = require("#openzeppelin/test-helpers");
const EventHandler = artifacts.require("EventHandler");
contract("Roles", function([_, superAdmin0, superAdmin1, admin0, device0]) {
beforeEach(async function() {
this.EventHandler = await EventHandler.new(superAdmin0);
});
it("...should work", async function() {});
});
When I comment the content of one file, or just what's inside contract(..., {}), the other file works just fine and the tests pass successfully.
However, whenever I leave those 2 files uncommented, I get a massive error:
Error: Returned values aren't valid, did it run Out of Gas?
Of course, resetting ganache-cli didn't solve anything...
Does anyone know where it could come from?
I am using protractor-cucumber-framework for my test automation. I have multiple feature files. Each feature file has multiple scenarios. I am using "cucumber-html-reporter" to get HTML report of test execution. This HTML report gives detail information about total number of features and total number of scenarios that was executed. So after test execution only I come to know 'total number of feature files' and 'total number of Scenarios' that I was executed.
Is there any command OR plugin available to get
Total number of features
Total number of scenarios in each feature file
In my JavaScript test automation ?
This is quite simple to achieve without plugins.
Why not create an object with the feature names as the key, and the scenario count as the value, and either console.log() it, or save it to a file to view later?
I'll show both ways (2.x syntax and 1.x syntax, just so I've covered the bases).
CucumberJS 2.x Syntax
let {defineSupportCode} = require('cucumber'),
counter = {};
defineSupportCode(({registerHandler, Before}) => {
registerHandler('BeforeFeature', function (feature, callback) {
global.featureName = function () {
return feature.name;
};
callback();
});
Before(function (scenario, callback){
counter[featureName()] !== undefined ? counter[featureName()] += 1 : counter[featureName()] = 1;
callback();
});
registerHandler('AfterFeatures', function (feature, callback) {
console.log(JSON.stringify(counter));
callback();
});
});
CucumberJS 1.x Syntax
var counter = {};
module.exports = function () {
this.BeforeFeature(function (feature, callback) {
global.featureName = function () {
return feature.name;
};
callback();
});
this.Before(function (scenario, callback){
counter[featureName()] !== undefined ? counter[featureName()] += 1 : counter[featureName()] = 1;
callback();
});
this.AfterFeatures(function (feature, callback) {
console.log(JSON.stringify(counter));
callback();
});
};
Extra
If you want to save this to a file, so that you can see it at a later stage, I recommend using the fs-extra library. In place of the console.log(), use this:
fs = require('fs-extra');
fs.writeFileSync("path/to/file.js","let suite = " + JSON.stringify(counter));
Please note, the file will be created from where you ran the the tests.
Given I am running from "frameworks/cucumberjs"
When I generate a file from "frameworks/cucumberjs/hooks/counter.js" with the fs library at "./file.js"
Then the file "frameworks/cucumberjs/file.js" should exist
Given I am running from "frameworks/cucumberjs"
When I generate a file from "frameworks/cucumberjs/features/support/hooks/counter.js" with the fs library at "./hello/file.js"
Then the file "frameworks/cucumberjs/hello/file.js" should exist
Just make sure that you are running from the right directory.
Total Number of Features
If you want the total number of features as well:
In place of the console.log():
console.log(JSON.stringify(counter) + "\nFeature Count: " + Object.keys(counter).length)
And in place of the writeFile:
fs.writeFileSync("path/to/file.js","let suite = " + JSON.stringify(counter) + ", featureCount = " + Object.keys(counter).length);
As we have got the scenario count sorted by each feature name, stating the amount of keys within the object we have created will give us the count of the number of features.
A versatile JS script for that involves parsing the feature files using Gherkin to a AST and count Features, Scenarios, Tags, etc.. from that structure:
eg:
const glob = require('glob')
const Gherkin = require('gherkin')
const parser = new Gherkin.Parser()
const AST = glob
.sync('./specifications/**/*.feature')
.map(path => parser.parse(fs.readFileSync(path).toString()))
From there you can traverse the AST object and extract features/scenarios counts and all other information needed.
the following lamdba code works perfectly fine when testing locally using Alex-app-server but when published and tested on AWS Lambda, it gets within the else statement and prints the console.log('OUT PUBLISH') But it doesn't publish the 'lambda/channelnumber' nor does it send the correct response back to me or print 'IN PUBLISH'
Any ideas why its just completing the bottom half of the else statement and not touching the publish function?
Code Snippet where I believe the problem lies
function (request, response) {
var channelNumber = request.slot('CHANNELNUMBER');
if (_.isEmpty(channelNumber)) {
var prompt = 'I didn\'t hear a channel code. Tell me a channel code.';
response.say(prompt).shouldEndSession(true);
return true;
} else {
//Doesn't publish any of this?????
thingShadows.publish('lambda/channelNumber', channelNumber, function () {
var prompt1 = 'Okay.';
response.say(prompt1).shouldEndSession(true);
console.log('in publish');
});
////But prints this??
console.log('out publish');
return true;
}
}
Full Code
'use strict';
module.change_code = 1;
var Alexa = require('alexa-app');
var skill = new Alexa.app('smartmote');
var awsIot = require('aws-iot-device-sdk');
var deviceName = "tv";
var _ = require('lodash');
var path = require('path');
var host = "XXXXXXXXXXXXXXXXXXXX.iot.us-east-1.amazonaws.com";
//App id is the skill being used.
var app_id = "amzn1.ask.skill.YYYYYYYYYYYYYYYYYYYYY";
var thingShadows = awsIot.thingShadow({
keyPath: path.join(__dirname, '/Raspi.private.key'),
certPath: path.join(__dirname, '/Raspi.cert.pem'),
caPath: path.join(__dirname, '/root-CA.crt'),
clientId: deviceName,
region: "us-east-1",
});
var reprompt = 'I didn\'t hear a channel, tell me a channel number or name to change to that channel';
skill.launch(function (request, response) {
var prompt = 'To change channel, tell me a channel number.';
response.say(prompt).reprompt(reprompt).shouldEndSession(true);
});
skill.intent('ChannelNumberIntent', {
'slots': {
'CHANNELNUMBER': 'CHANNELID'
},
'utterances': ['{|Change|put} {|the|on} {|channel} {|to} {-|CHANNELNUMBER}']
},
function (request, response) {
var channelNumber = request.slot('CHANNELNUMBER');
if (_.isEmpty(channelNumber)) {
var prompt = 'I didn\'t hear a channel code. Tell me a channel code.';
response.say(prompt).shouldEndSession(true);
return true;
} else {
thingShadows.publish('lambda/channelNumber', channelNumber, function () {
console.log('in pub');
var prompt1 = 'Okay.';
response.say(prompt1).shouldEndSession(true);
callback();
});
console.log('out pub');
return true;
}
}
);
module.exports = skill;
This is most likely because of the asynchronous nature of your code.
You haven't told us what thingShadows.publish() does, but it appears to take a callback function as its second argument. Presumably this function will be called when publish() has finished doing whatever it does.
When running locally I would imagine that the output you see is (in this order):
out publish
in publish
Notice that out publish gets called before in publish. This is because the publish method is asynchronous, so execution will continue as soon as it is called. In your case, you are calling return immediately after calling publish, which probably means your lambda job is ending before it has a chance to log in publish.
You haven't provided enough information about the rest of your lambda code/setup to provide a full answer, but you need to make sure that you are waiting for your publish method to have finished before continuing. One way to achieve this is to use the callback object that is passed to your lambda handler:
exports.myHandler = function(event, context, callback) {
// Other code
thingShadows.publish('lambda/channelNumber', channelNumber, function () {
var prompt1 = 'Okay.';
response.say(prompt1).shouldEndSession(true);
console.log('in publish');
// When the publish method is complete, we can call `callback`
// to tell lambda we are done
callback();
});
}
I am writing test cases for NODE JS API. But wherever console.log() is there in routes or services of NODE JS File, it gets printed to CLI. Is there a way to mock these so that these won't get printed in CLI.
I have explored couple of libraries like Sinon, Stub for mocking. But couldn't grasp the working of those libraries.
You can override function entirely: console.log = function () {}.
You should not try to mock console.log itself, a better approach is for your node modules to take a logging object. This allows you to provide an alternative (ie. a mock) during testing. For example:
<my_logger.js>
module.exports = {
err: function(message) {
console.log(message);
}
}
<my_module.js>
var DefaultLogger = require('my_logger.js');
module.exports = function(logger) {
this.log = logger || DefaultLogger;
// Other setup goes here
};
module.exports.prototype.myMethod = function() {
this.log.err('Error message.');
};
<my_module_test.js>
var MyModule = require('my_module.js');
describe('Test Example', function() {
var log_mock = { err: function(msg) {} };
it('Should not output anything.', function() {
var obj = new MyModule(log_mock);
obj.myMethod();
});
});
The code here I've simplified, as the actual test isn't the reason for the example. Merely the insertion of alternative logging.
If you have a large codebase with lots of console.log calls, it is better to simply update the code as you add tests for each method. Making your logging pluggable in this way makes your code easier and more receptive to testing. Also, there are many logging frameworks available for node. console.log is fine during development when you just want to dump out something to see what's going on. But, if possible, try to avoid using it as your logging solution.
I could not find a solution which only hides the console.log calls in the module to be tested, and mocks none of the calls of the testing framework (mocha/chai in my case).
I came up with using a copy of console in the app code:
/* console.js */
module.exports = console;
/* app.js */
const console = require('./console');
console.log("I'm hidden in the tests");
/* app.spec.js */
const mockery = require('mockery');
var app;
before(() => {
// Mock console
var consoleMock = {
log: () => {}
}
mockery.registerMock('./console', consoleMock);
// Require test module after mocking
app = require('./app');
});
after(() => {
mockery.deregisterAll();
mockery.disable();
});
it('works', () => {});
You could do something along the lines of adding these before/after blocks to your tests, but the issue is that mocha actually uses console.log to print the pretty messages about the results of the test, so you would lose those
describe('Test Name', function() {
var originalLog;
beforeEach(function() {
originalLog = console.log;
console.log = function () {};
});
// test code here
afterEach(function() {
console.log = originalLog;
})
})
The problem is that your output would just look like
Test Name
X passing (Yms)
Without any intermediate text