Protractor: commands in afterLaunch don't run - protractor

I'm trying to send an email out with results after tests have finished running.
When I put the sendgrid call in the onComplete section, then the email sends. However, the report is empty since it hasn't finished saving.
If I put the sendgrid call into the afterLaunch section, then the file is saved. However, it doesn't seem to run the sendgrid command.
This is the config that I am using:
var HtmlReporter = require ('protractor-jasmine2-html-reporter');
var browser = "chrome";
var environment = "dev";
var pname = "";
var pversion = "";
var dname = "";
var selenium_address = "http://localhost:4444/wd/hub";
var folder_name = (new Date()).toString().split(' ').splice(0,3).join('');
var report_folder = "./test/e2e/reports/" + folder_name + "_" + browser + "_" + environment + "/";
var reporter = new HtmlReporter({
savePath: report_folder,
takeScreenshots: false,
cleanDestination: true,
fileName: 'CE_Smoketest'
});
function test_function() {
var report = report_folder + 'CE_Smoketest.html'
var sendgrid = require('sendgrid')('xxxxx', 'xxxxxxxxx');
var email = new sendgrid.Email();
email.addTo("destination#mail.com");
email.setFrom("Smoketest#mail.com");
email.setSubject("Smoketest");
email.setHtml("Smoketest results");
email.addFile({filename: report});
sendgrid.send(email);
}
exports.config = {
//appium setup
seleniumAddress: selenium_address,
multiCapabilities: [
{
'browserName' : browser,
platformName : pname,
platformVersion : pversion,
deviceName: dname
}
],
getPageTimeout: 50000,
allScriptsTimeout: 50000,
jasmineNodeOpts: {
defaultTimeoutInterval: 50000,
isVerbose: true
},
onPrepare: function() {
jasmine.getEnv().addReporter(reporter);
},
onComplete: function(exitCode) {
test_function();
},
afterLaunch: function(exitCode) {
test_function();
}
}
Any ideas as to why afterLaunch doesn't send the email?

In afterLaunch methods, Webdriver instance have been shutdow(Not available). That's you code will get executed. Check description of afterLaunch() method below:
/**
* A callback function called once all tests have finished running and
* the WebDriver instance has been shut down. It is passed the exit
code
* (0 if the tests passed). afterLaunch must return a promise if you
want
* asynchronous code to be executed before the program exits.
* This is called only once before the program exits (after onCleanUp).
*/

Suresh is right, you must return a promise if you want asynchronous code to be executed before the program exits
Try this:
1- Declare new var
var q = require('q');
2- Refactor your afterLaunch
afterLaunch: function(exitCode) {
return q.fcall(function () {
test_function();
}).delay(1000);
}

Related

Error attempting to retrieve CODE sent to gmail account using MailListener Protractor/Jasmine end to end Test

I have already installed MailListener
npm install mail-listener2 --save-dev
In My Config.js file, I have
exports.config = {
directConnect: true,
capabilities: {
browserName: 'chrome',
},
framework: 'jasmine2',
onPrepare: function () {
var AllureReporter = require('jasmine-allure-reporter');
var AllureReporter = require('../index');
jasmine.getEnv().addReporter(new AllureReporter({
resultsDir: 'allure-results'
}));
// Mail Listener
var MailListener = require("mail-listener2");
// here goes your email connection configuration
var mailListener = new MailListener({
username: "myemail#gmail.com",
password: "mygmailpassword!",
host: "imap.gmail.com",
port: 993, // imap port
tls: true,
tlsOptions: { rejectUnauthorized: false },
mailbox: "INBOX", // mailbox to monitor
searchFilter: ["UNSEEN", "FLAGGED"], // the search filter being used after an IDLE notification has been retrieved
markSeen: true, // all fetched email willbe marked as seen and not fetched next time
fetchUnreadOnStart: true, // use it only if you want to get all unread email on lib start. Default is `false`,
mailParserOptions: { streamAttachments: true }, // options to be passed to mailParser lib.
attachments: true, // download attachments as they are encountered to the project directory
attachmentOptions: { directory: "attachments/" } // specify a download directory for attachments
});
mailListener.start();
mailListener.on("server:connected", function () {
console.log("... Mail listener initialized");
});
global.mailListener = mailListener;
},
onCleanUp: function () {
mailListener.stop();
},
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: [
'../e2e/login_spec.js'
],
// Options to be passed to Jasmine.
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
}
};
in my login_spec.js file i have the function
function getLastEmail() {
var deferred = protractor.promise.defer();
console.log("Waiting for an email...");
mailListener.on("mail", function(mail){
deferred.fulfill(mail);
});
return deferred.promise;
};
In the Same login_spec.js
i am trying
var loginData = require('../data.json');
var Login_Objects = require('../page_objects/login_objects');
describe('2Factor Login:', function () {
dataProvider(loginData, function (data) {
Login_Objects.EnterUserName(data.username)
Login_Objects.EnterUserName(data.password)
Login_Objects.ClickLogin()
//Code is sent to email
browser.controlFlow().wait(getLastEmail()).then(function (email){
var pattern = /Code for your transfer (\w+)/g;
var regCode = pattern.exec(email.text)[1];
console.log("Registration code : = "+regCode);
//Pass the code to my methods in the objects file.
//Login_Objects.Enter2FactorCode(regCode)
//Login_Objects.ClickVerify()
})
})
})
here my Login_Objects.Enter2FactorCode(regCode) method will just send keys to the 2factor webelement [but i am not yet at that stage]
At this point i am expecting the email to be printed by the function
console.log("Registration code : = "+regCode);
On the Console I am Getting the message :
... Mail listener initialized
NOTE: I have already allowed unsecure apps to access that gmail account
Findings:
I am getting an error
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
My reference is this >> Fetching values from email in protractor test case

gulp task with gulp-run-command doesn't work properly

I'm trying to run json-server in a gulp task and I'm checking if the server runs, with the function portInUse.
Like this:
var gulputil = require('gulp-util')
var run = require('gulp-run-command').default
var gulp = require('gulp')
const args = [
'json-server --watch .\\src\\main\\app\\reactjs\\api\\db.json --port 3005'
]
var net = require('net');
var portInUse = function(port, callback) {
var server = net.createServer(function(socket) {
socket.write('Echo server\r\n');
socket.pipe(socket);
});
server.listen(port, '127.0.0.1');
server.on('error', function (e) {
callback(true);
});
server.on('listening', function (e) {
server.close();
callback(false);
});
};
gulp.task("initLocalJsonServer", function() {
portInUse(3005, function(returnValue) {
gulputil.log('1 ' + returnValue);
});
run(args);
portInUse(3005, function(returnValue) {
gulputil.log('2 ' + returnValue);
});
});
That command that is the value of args here, works as intended when I run it in command line, so there's nothing wrong with the command or json-server itself. If I run it, I get to see the json-server at localhost:3005
Now the output from the portInUse function indicates that the server starts, as the output is:
[10:33:56] 1 false
[10:33:56] 2 true
But if I go to localhost:3005 after the gulp tasks are done, I can't see any server running. What might be the reason?

jupyter-js-services - how to save notebook

I'm trying to use jupyter as a backend for my system and now I play with examples from jupyter-js-api docs.
Using IKernel and INotebookSession I managed to execute simple code and get the response form kernel.
But I can's figure out how to extract the notebook itself. there's nothing like "saveNotebook()" in API. I try to execute session.renameNotebook(), it completes successfully, but no files appear in filesystem (tried different paths like "/tmp/trynote.ipynb" "trynote.ipnb" and so on...).
Here's the code, it is slightly edited example from http://jupyter.org/jupyter-js-services/ page
#!/usr/bin/env node
var jpt = require("jupyter-js-services");
var xr = require("xmlhttprequest");
var ws = require("ws");
global.XMLHttpRequest = xr.XMLHttpRequest;
global.WebSocket = ws;
// start a new session
var options = {
baseUrl: 'http://localhost:8889',
wsUrl: 'ws://localhost:8889',
kernelName: 'python',
notebookPath: 'trynote.ipynb'
};
jpt.startNewSession(options).then((session) => {
// execute and handle replies on the kernel
var future = session.kernel.execute({ code: 'print(5 * 5);' });
future.onDone = (msg) => {
console.log('Future is fulfilled: ');
console.log(msg);
};
future.onIOPub = (msg) => {
console.log("Message in IOPub: ");
console.log(msg);
};
// rename the notebook
session.renameNotebook('trynote2.ipynb').then(() => {
console.log('Notebook renamed to', session.notebookPath);
});
// register a callback for when the session dies
session.sessionDied.connect(() => {
console.log('session died');
});
// kill the session
session.shutdown().then(() => {
console.log('session closed');
});
});
Looking and ContentManager API it seems to work with already existing files, or creating new ones, but its unclear how is it bound to sessions.
More, even simplest try to use "newUntitled" function gives 404 response...
var contents = new jpt.ContentsManager('http://localhost:8889');
// create a new python file
contents.newUntitled("foo", { type: "file", ext: "py" }).then(
(model) => {
console.log(model.path);
}
);
I feel a bit disoriented with all this and would appreciate any explanations.
Thanks..

Log in to Facebook with phantomjs - 302 issues?

I'm trying to write a phantomjs script to log in to my facebook account and take a screenshot.
Here's my code:
var page = require('webpage').create();
var system = require('system');
var stepIndex = 0;
var loadInProgress = false;
email = system.args[1];
password = system.args[2];
page.onLoadStarted = function() {
loadInProgress = true;
console.log("load started");
};
page.onLoadFinished = function() {
loadInProgress = false;
console.log("load finished");
};
var steps = [
function() {
page.open("http://www.facebook.com/login.php", function(status) {
page.evaluate(function(email, password) {
document.querySelector("input[name='email']").value = email;
document.querySelector("input[name='pass']").value = password;
document.querySelector("#login_form").submit();
console.log("Login submitted!");
}, email, password);
page.render('output.png');
});
},
function() {
console.log(document.documentElement.innerHTML);
},
function() {
phantom.exit();
}
]
setInterval(function() {
if (!loadInProgress && typeof steps[stepIndex] == "function") {
console.log("step " + (stepIndex + 1));
steps[stepIndex]();
stepIndex++;
}
if (typeof steps[stepIndex] != "function") {
console.log("test complete!");
phantom.exit();
}
}, 10000);
(Inspired by this answer, but note that I've upped the interval to 10s)
Called like so:
./phantomjs test.js <email> <password>
With output (filtering out the selfxss warnings from Facebook):
step 1
load started
load finished
Login submitted!
load started
load finished
step 2
<head></head><body></body>
step 3
test
complete!
(Note that the html output in step two is empty)
This answer suggests that there are problems with phantomjs' SSL options, but running with --ssl-protocol=any has no effect.
This appears to be a similar problem, but for caspar, not phantomjs (and on Windows, not Mac) - I've tried using --ignore-ssl-errors=yes, but that also had no effect.
I guessed that this might be a redirection problem (and, indeed, when I replicate this on Chrome, the response from clicking "Submit" was a 302 Found with location https://www.facebook.com/checkpoint/?next), but according to this documentation I can set a page.onNavigationRequested handler - when I do so in my script, it doesn't get called.
I think this issue is related, but it looks as if there's no fix there.

Emberjs-CLI web socket

I am attempting to create a web socket for use in my EmberJS app that I have created using the cli. I am a bit unsure of what logic goes where, so let me know if I did this incorrectly.
I have an Adapter that should create a connection and then handle any request that is made to the server that I am connecting to. I am unsure of how to reference this socket in my controller.
export default DS.Adapter.extend({
url: '<my connection bruh>',
qSocket: null,
deferred: $.Deferred(),
defResolve: function(res){
this.deferred.resolve(res);
},
init: function(uri){
var qsservice = this;
if(arguments.length==1&&uri.length>4){
this.url=uri;
}
this.qSocket = new WebSocket(this.url);
this.qSocket.onopen = function(evt){console.log('CONNECTED');};
this.qSocket.onclose = function(evt){console.log('DISCONNECTED');};
this.qSocket.onmessage = function(evt){console.log('RESPONSE: '+evt.data);
qsservice.deferred.resolve(evt.data);};
this.qSocket.onerror = function(evt){console.log('ERROR');
qsservice.deferred.reject(evt);};
},
sendMessage: function (msg) {
return this.qSocket.send(msg);
},
disconnect: function(){
this.qSocket.close();
},
isConnected: function(){
return this.qSocket ? true : false;
},
getDocList: function(){
this.qSocket.send(JSON.stringify(GetDocList));
return this.deferred.promise();
}
});
How would I call any of these functions from, say, the index controller?