How to add custom logs in Protractor test reports - protractor

I'm trying to add some custom logs to my protractor test report. I've app log file in my project folder which has the logs captured using log4js. I want these log entries to be shown in my test report as well. Currently I'm using chercher report. Since I'm a beginner to protractor, I'm not sure how to do this. Can anybody help me on this? Thanks in advance!
spec.js
fdescribe('Protractor Perfecto Demo', function () {
it('should pass test', function () {
browser.reportingClient.stepStart('Step 1: Navigate Google');
browser.driver.get('https://www.google.com'); //Navigate to google.com
browser.reportingClient.stepEnd();
//Locate the search box element and insert text
//Click on search button
browser.reportingClient.stepStart('Step 2: Send Keys');
browser.driver.findElement(by.name('q')).sendKeys('PerfectoCode GitHub');
browser.reportingClient.stepEnd();
browser.reportingClient.stepStart('Step 3: Click');
browser.driver.findElement(by.css('#tsbb > div')).click();
browser.reportingClient.stepEnd();
});
//This test should fail
it('should fail test', function () {
browser.reportingClient.stepStart('Step 1: Navigate Google');
browser.driver.get('https://www.google.com'); //Navigate to google.com
browser.reportingClient.stepEnd();
//Locate the search box element and insert text
//Click on search button
browser.reportingClient.stepStart('Step 2: Send Keys');
browser.driver.findElement(by.name('q')).sendKeys('PerfectoCode GitHub');
browser.reportingClient.stepEnd();
browser.reportingClient.stepStart('Step 3: Click');
browser.driver.findElement(by.css('#tsbbbsdasd > div')).click();
browser.reportingClient.stepEnd();
});
afterAll(function(done){
process.nextTick(done);
});
});
conf.js
var reportingClient;
exports.config = {
//Remote address
// seleniumAddress: 'https://MY_HOST.perfectomobile.com/nexperience/perfectomobile/wd/hub',
directConnect: true,
//Capabilities to be passed to the webdriver instance.
capabilities: {
browserName: 'chrome'
// user: 'MY_USER',
// password: 'MY_PASS',
// platformName: 'Android',
//deviceName: '123456',
},
//Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directly when
// protractor is called.
specs: ['./tests/SignupAutomation_spec.js'],
// Options to be passed to Jasmine.
jasmineNodeOpts: {
showColors: true, // Use colors in the command line report.
defaultTimeoutInterval: 120000 // Time to wait in ms before a test fails. Default value = 30000
},
onComplete: function () {
// Output report URL
return reportingClient.getReportUrl().then(
function (url) {
console.log(`Report url = ${url}`);
}
);
},
onPrepare: function () {
const Reporting = require('perfecto-reporting');
reportingClient = new Reporting.Perfecto.PerfectoReportingClient(new Reporting.Perfecto.PerfectoExecutionContext({
webdriver: browser.driver,
tags: ['javascript driver']
}));
browser.reportingClient = reportingClient;
var myReporter = {
specStarted: function (result) {
reportingClient.testStart(result.fullName);
},
specDone: function (result) {
if (result.status === 'failed') {
const failure = result.failedExpectations[result.failedExpectations.length - 1];
reportingClient.testStop({
status: Reporting.Constants.results.failed,
message: `${failure.message} ${failure.stack}`
});
} else {
reportingClient.testStop({
status: Reporting.Constants.results.passed
});
}
}
}
jasmine.getEnv().addReporter(myReporter);
}
}
While running this I'm getting below error:
An error was thrown in an afterAll
AfterAll JavascriptError: javascript error: end is not defined
(Session info: chrome=90.0.4430.212)
(Driver info: chromedriver=90.0.4430.24 (4c6d850f087da467d926e8eddb76550aed655991-refs/branch-heads/4430#{#429}),platform=Windows NT 10.0.19042 x86_64)

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

How to make local connections to crossbrowsertesting.com with Protractor?

How can I test my Angular Pages with Protractor in my local network at crosbrowsertesting.com? I installed "npm i cbt_tunnels" and my protractor.conf looks like this:
const cbt = require('cbt_tunnels');
export.config= {
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
directConnect: false,
seleniumAddress: 'http://<myusername>:<mykey>#hub.crossbrowsertesting.com:80/wd/hub',
capabilities : {
name : 'protractor test', // this will show up in the UI
// these are important :)
browserName : "firefox",
browser_api_name : 'FF39', // change this according to what browser you are using
os_api_name : 'Win10', // change this for the OS you are using
screen_resolution : '1024x768', // change this for the resolution
record_video : 'true',
record_network : 'true',
record_snapshot : 'true',
acceptInsecureCerts: 'true',
tunnel: 'true'
},
onComplete: () => {
browser.quit();
},
onPrepare() {
cbt.start({"username": "<myusername>", "authkey":
"<mykey>"}, function (err) {
if (!err) console.log("cbt success");
});
}
I can see the test running at crossbrowsertesting.com but the browser there says:
waiting for localhost
What is missing?
As the commenter noted, you need to start the local connection before you can actually use the local connection feature.
In this case, you will want to use this line:
'cbt.start({"username":"USERNAME","authkey":"AUTHKEY"},function(err){ if(!err) do stuff })'
from the documentation; this will allow you to automatically start the test once the local connection has been set up correctly.
In this case, do stuff is everything to run your tests (scaffolding/setup can be done externally).
Something like this is what you're really after
const cbt = require('cbt_tunnels');
cbt.start({"username":"USERNAME","authkey":"AUTHKEY"},
function(err){
if(!err) do stuff
});
Edit:
It looks like you want to start the tunnel in beforeLaunch, instead of in onPrepare, and it needs to be set as a promise. Something like this:
beforeLaunch: () => {
return new Promise( (resolve, reject) => {
cbt.start({"username": "<your email here>", "authkey": "<your auth here>"}, function (err) {
if (!err) {
console.log("cbt success");
return resolve();
}
return reject(err);
});
})
}

Protractor : not able to find element in login page

I am novice user of protractor and trying to use it for angularjs application,
Config file snippet :
exports.config = {
directConnect: true,
capabilities: {
'browserName': 'chrome'
},
framework: 'jasmine',
specs: ['plugins/./test_spec.js'],
allScriptsTimeout: 60000,
getPageTimeout: 30000,
jasmineNodeOpts: {
defaultTimeoutInterval: 1240000
}
};
Working test case (spec file):
describe('Login', function () {
it('Login Page', function () {
browser.get('http://localhost:9000/apps/admin/');
element(by.model('ctrl.user.name'))
element(by.model('ctrl.user.password'))
expect(true).toBe(true)
});
});
Failing test case (spec file):
describe('Login', function () {
it('Login Page', function () {
browser.get('http://localhost:9000/apps/admin/');
element(by.model('ctrl.user.name')).sendKeys("test1");
element(by.model('ctrl.user.password')).sendKeys("test1");
element(by.css('[type="submit"]')).click();
expect(true).toBe(true)
});
});
Trying to use sendKeys for login page is failing but without sendkeys test case passes, I am getting following error:
Failed: script timeout: result was not received in 60 seconds
(Session info: chrome = 72.0.3626.109)
(Driver info: chromedriver = 2.46.628402(536cd7adbad73a3783fdc2cab92ab2ba7ec361e1), platform = Windows NT 10.0.17134 x86_64)
I suspect element not being found.
Please guide me through this.
Thanks in Advance
I highly recommended to add SELENIUM_PROMISE_MANAGER: false, to your protractor.config file due to this thread, if tells it shortly - better to don't use Control Flow. So how will look your config file:
exports.config = {
directConnect: true,
capabilities: {
'browserName': 'chrome'
},
framework: 'jasmine',
specs: ['plugins/./test_spec.js'],
allScriptsTimeout: 60000,
getPageTimeout: 30000,
jasmineNodeOpts: {
defaultTimeoutInterval: 1240000
},
SELENIUM_PROMISE_MANAGER: false,
};
After it you should update your tests (all actions that returns promise should resolve it, I prefer async ... await style). Also, your expect true is useless, let get rid off it, and add some explicit waiters.
describe('Login', () => {
it('Login Page' async () => {
await browser.get('http://localhost:9000/apps/admin/');
const name = element(by.model('ctrl.user.name'));
await browser.wait(ExpectedConditions.elementToBeClickable(name), 10000);
await name.sendKeys("test1");
const password = element(by.model('ctrl.user.password'));
await browser.wait(ExpectedConditions.elementToBeClickable(password), 10000);
await password.sendKeys("test1");
element(by.css('[type="submit"]')).click();
expect(true).toBe(true)
});
});
Also, It would be better to find locators using CSS. Update your question with what error this test will fail.
Protractor is wrapper on selenium, thus when you are plainning to use await/async methods just disable the SELENIUM_PROMISE_MANAGER by setting it as false, so that the protractor promises work well with async/await methods.
I also suggest using pagemodel design pattern which will make the code much readable.
enter code here
export class loginPageObject{
public emailTextBox: ElementFinder;
public passwordTextBox: ElementFinder;
public signInButton: ElementFinder;
public errorMessage: ElementFinder;
constructor(){ //this.emailTextBox = $("input[type='email']");
//this.emailTextBox = element(by.css("body > app-root > div > app-login > div > div > form > div > input"));
this.emailTextBox = $("input[type='email']");
this.passwordTextBox = $("input[type='password']");
this.signInButton = $("button[type='submit']");
this.errorMessage = $("span");
}
}
above is one such sample .. later on you can use it like following way

testing a site not working in internet explorer-values not able to enter in fields

I am using protractor version 5.2.2 and cucumber-protractor framework, I have started practising testing for the LinkedIn site, but when I use the internet explorer browser it is only able to open the LinkedIn URL as mentioned in the config file and no scenarios are being executed, can anybody help me?
//config file
var params = require('./browsers.js');
var browser = params.browser;
var multiCapabilities = browser.split(',').map(function(browserName){
return {
browserName: browserName.trim()
};
})
var moment = require('moment')
var timeStamp = moment().format('YYYYMMDD_hhmmss');
exports.config = {
seleniumAddress: 'http://127.0.0.1:4444/wd/hub',
getPageTimeout: 60000,
allScriptsTimeout: 500000,
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
// Capabilities to be passed to the webdriver instance.
multiCapabilities: multiCapabilities,
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['Features/*.feature'],
baseUrl: 'https://www.linkedin.com/',
cucumberOpts: {
require: 'Features/step_definition/searchstep_linkedin.js',
tags: false,
plugin: ['pretty'],
format: 'json:reports/report'+timeStamp+' '+browser+'/results.json',
profile: false,
'no-source': true
},
plugins: [{
package: 'protractor-multiple-cucumber-html-reporter-plugin',
options:{
automaticallyGenerateReport: true,
}
}]
};
//Feature file
Background: I need to go linked in site
Given I go to url ""
Scenario: Should not login with blank username and password
Then I wait for "2000"
When I enter " " in "#login-email"
When I enter " " in "#login-password"
Then I click on "#login-submit"
Then I should see ""
//Spec File
Given(/^I go to url "(.*)"$/, function (url){
return browser.get(url);
});
When(/^I enter "(.*)" in "(.*)"$/, function (value,locator){ /**/
return element(by.xpath(locator)).sendKeys(value);
});
Then(/^I should see "(.*)"$/, function (url){ /**/
browser.sleep(2000);
return
expect(browser.getCurrentUrl()).to.eventually.equal(browser.baseUrl
+ url);
});
Then(/^I click on "(.*)"$/, function (locator){ /**/
return return element(by.xpath(locator)).click();
});

Protractor- Non angular OAuth Login redirecting to angular site

We are using Protractor+Cucumber+Typescript combination.
Using protractor we are trying to login (Non angular OAuth) which redirects to application page (angular site). Following is our setup
feature file:
docsLogin.feature
Feature: Login to Docs
#TendukeLoginScenario
Scenario: Login to Docs application
Given I am on Tenduke login page
When Enter username and password
Then I click on Sign in button
Then I create a new folder
docsLoginPage.ts
import { $, element,by } from 'protractor';
export class TendukeLoginPageObject {
public usernameTextBox: any;
public passwordTextBox: any;
public signInButton: any;
public search: any;
public searchBox: any;
constructor() {
this.usernameTextBox = $("input[name='userName']");
this.passwordTextBox = $("input[name='password']");
this.signInButton = $("button[class='btn btn-primary']");
this.search = $("span[class='fa fa-search']");
this.searchBox = element(by.model('searchString'));
}
}
tenDukeLogin.ts
import { browser,element, by, } from 'protractor';
import { TendukeLoginPageObject } from '../pages/docsLoginPage';
import { defineSupportCode } from 'cucumber';
let chai = require('chai').use(require('chai-as-promised'));
let expect = chai.expect;
defineSupportCode(function ({ Given, When, Then }) {
let login: TendukeLoginPageObject = new TendukeLoginPageObject();
Given(/^I am on Tenduke login page$/, async () => {
browser.waitForAngularEnabled(false);
await expect(browser.getTitle()).to.eventually.equal('Sign in');
});
When(/^Enter username and password$/, async () => {
await login.usernameTextBox.sendKeys('abc#abc.com');
await login.passwordTextBox.sendKeys('12345');
});
Then(/^I click on Sign in button$/, async () => {
await (login.signInButton.click()).then(function(){
//browser.driver.wait((docs.plusIcon), 15000);
browser.wait((login.search).isPresent);
});
//await expect(browser.getTitle()).to.eventually.equal('Docs');
});
Then(/^I create a new folder$/, async () => {
//await browser.sleep(40000);
browser.waitForAngularEnabled();
await (login.search.click()).then(function(){
browser.wait((login.searchBox).isPresent);
});
});
})
Config.ts
import { browser, Config } from 'protractor';
export let config: Config = {
seleniumAddress: 'http://127.0.0.1:4444/wd/hub',
SELENIUM_PROMISE_MANAGER: false,
baseUrl: 'http://abc/content',
capabilities: {
browserName: 'chrome'
},
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
specs: [
'../../features/docsLogin.feature'
],
onPrepare: () => {
browser.ignoreSynchronization = true;
browser.manage().window().maximize();
},
cucumberOpts: {
compiler: "ts:ts-node/register",
strict: true,
format: ['pretty'],
require: ['../../stepdefinitions/*.ts', '../../support/*.ts'],
tags: '#TypeScriptScenario or #CucumberScenario or
#TendukeLoginScenario'
}
};
After clicking Sign in button browser closing immediately before
loading the application page.
We tried even adding some wait statement after Sign in but after timeout browser is closing. Not able to perform any action on Angular page after login.
protractor-typescript-cucumber#2.0.0 test E:\ProtractorTest\protractor-
cucumber-typescript
protractor typeScript/config/config.js
[18:10:52] I/launcher - Running 1 instances of WebDriver
[18:10:52] I/hosted - Using the selenium server at
http://127.0.0.1:4444/wd/hub
Feature: Login to Docs
#TendukeLoginScenario
Scenario: Login to Docs application
√ Given I am on Tenduke login page
√ When Enter username and password
(node:9096) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): TypeError: Cannot read property 'parentElementArrayFinder' of undefined
√ Then I click on Sign in button
x Then I create a new folder
Failures:
1) Scenario: Login to Docs application - features\docsLogin.feature:4
Step: Then I create a new folder - features\docsLogin.feature:8
Step Definition: stepdefinitions\tenDukeLogin.ts:29
Message:
NoSuchElementError: No element found using locator: By(css selector,
span[class='fa fa-search'])
at WebDriverError (E:\ProtractorTest\protractor-cucumber-
typescript\node_modules\selenium-webdriver\lib\error.js:27:5)
at NoSuchElementError (E:\ProtractorTest\protractor-cucumber-
typescript\node_modules\selenium-webdriver\lib\error.js:168:5)
at elementArrayFinder.getWebElements.then
(E:\ProtractorTest\protractor-cucumber-
typescript\node_modules\protractor\lib\element.ts:851:17)
at process._tickCallback (internal/process/next_tick.js:109:7)Error
at ElementArrayFinder.applyAction_ (E:\ProtractorTest\protractor-
cucumber-typescript\node_modules\protractor\lib\element.ts:482:23)
at ElementArrayFinder.(anonymous function) [as click]
(E:\ProtractorTest\protractor-cucumber-
typescript\node_modules\protractor\lib\element.ts:96:21)
at ElementFinder.(anonymous function) [as click]
(E:\ProtractorTest\protractor-cucumber-
typescript\node_modules\protractor\lib\element.ts:873:14)
at E:\ProtractorTest\protractor-cucumber-
typescript\stepdefinitions\tenDukeLogin.ts:32:29
at next (native)
at E:\ProtractorTest\protractor-cucumber-
typescript\stepdefinitions\tenDukeLogin.ts:7:71
at __awaiter (E:\ProtractorTest\protractor-cucumber-typescript\stepdefinitions\tenDukeLogin.ts:3:12)
at World.Then (E:\ProtractorTest\protractor-cucumber-typescript\stepdefinitions\tenDukeLogin.ts:29:37)
1 scenario (1 failed)
4 steps (1 failed, 3 passed)
0m04.194s
Cucumber HTML report E:\ProtractorTest\protractor-cucumber-
typescript/reports/html/cucumber_reporter.html generated successfully.
[18:11:03] I/launcher - 0 instance(s) of WebDriver still running
[18:11:03] I/launcher - chrome #01 failed 1 test(s)
[18:11:03] I/launcher - overall: 1 failed spec(s)
[18:11:03] E/launcher - Process exited with error code 1
npm ERR! Test failed. See above for more details.
Could you explain me why do you use async over there?
Do you have any other steps with asycn which works?
Try to replace tenDukeLogin.ts with:
import {defineSupportCode} from 'cucumber';
import {browser, ExpectedConditions} from 'protractor';
import {TendukeLoginPageObject} from '../pages/docsLoginPage';
const chai = require('chai').use(require('chai-as-promised'));
const expect = chai.expect;
defineSupportCode(({ Given, When, Then }) => {
const login: TendukeLoginPageObject = new TendukeLoginPageObject();
Given(/^I am on Tenduke login page$/, () => {
browser.waitForAngularEnabled(false);
return expect(browser.getTitle()).to.eventually.equal('Sign in');
});
When(/^Enter username and password$/, () => {
login.usernameTextBox.sendKeys('abc#abc.com');
return login.passwordTextBox.sendKeys('12345');
});
Then(/^I click on Sign in button$/, () => {
return (login.signInButton.click()).then(() => {
return browser.wait(ExpectedConditions.visibilityOf(login.search), 5000);
});
});
Then(/^I create a new folder$/, () => {
browser.waitForAngularEnabled();
return (login.search.click()).then(() => {
return browser.wait(ExpectedConditions.visibilityOf(login.searchBox), 5000);
});
});
});
Drop me a line does it fix your issue.