angular/protractor timing out with multiple form fields - forms

This is my first angular/protractor test for a login form. When running the test, it will test one form field at a time with no problem, but when adding the second field to test, it always times out. Is there a secret to testing form fields, I'm unaware of?
'use strict';
describe('Login', function () {
beforeEach(function () {
// URL is relative to baseUrl specified in config/test/protractor-e2e.conf.js
browser.get('');
// browser.get('');
// var account = browser.findElement(by.css('#sign-in-account'));
// var username = browser.findElement(by.css('#sign-in-username'));
// var password = browser.findElement(by.css('#sign-in-password'));
// var submit = browser.findElement(by.css('.button-primary'));
// submit.click();
});
it('should redirect user to first module they have access to after successful login', function () {
// Should successfully register a user
element(by.name('account')).sendKeys('test');
element(by.name('username')).sendKeys('test#testing.com');
// element(by.name('password')).sendKeys('1234');
// element(by.css('.button-primary')).click();
// Should move to register page
// expect(browser.getCurrentUrl()).toContain('silpada.kineticsupply.com/module/analytics');
// Should show the first name where the lock icon was
// expect(element(by.name('account')).getText()).toContain('test');
}, 50000);
});
/*
* config/test/protractor-e2e.conf.js
*
* Protractor end-to-end testing configuration
*/
exports.config = {
// ----- How to setup Selenium -----
//
// There are three ways to specify how to use Selenium. Specify one of the
// following:
//
// 1. seleniumServerJar - to start Selenium Standalone locally.
// 2. seleniumAddress - to connect to a Selenium server which is already
// running.
// 3. sauceUser/sauceKey - to use remote Selenium servers via SauceLabs.
// The location of the selenium standalone server .jar file.
seleniumServerJar: null,
// The port to start the selenium server on, or null if the server should
// find its own unused port.
seleniumPort: null,
// Chromedriver location is used to help the selenium standalone server
// find chromedriver. This will be passed to the selenium jar as
// the system property webdriver.chrome.driver. If null, selenium will
// attempt to find chromedriver using PATH.
chromeDriver: null,
// Additional command line options to pass to selenium. For example,
// if you need to change the browser timeout, use
// seleniumArgs: ['-browserTimeout=60'],
seleniumArgs: [],
// If sauceUser and sauceKey are specified, seleniumServerJar will be ignored.
// The tests will be run remotely using SauceLabs.
sauceUser: null,
sauceKey: null,
// The address of a running selenium server. If specified, Protractor will
// connect to an already running instance of selenium. This usually looks like
seleniumAddress: 'http://localhost:4444/wd/hub',
// ----- What tests to run -----
//
// Spec patterns are relative to the location of this config.
specs: [
'./e2e/**/login.js'
],
// ----- Capabilities to be passed to the webdriver instance ----
//
// For a full list of available capabilities, see
// https://code.google.com/p/selenium/wiki/DesiredCapabilities
// and
// https://code.google.com/p/selenium/source/browse/javascript/webdriver/capabilities.js
capabilities: {
'browserName': 'chrome'
},
// A base URL for your application under test. Calls to protractor.get()
// with relative paths will be prepended with this.
//baseUrl: 'http://localhost:8081',
baseUrl: 'http://silpada.kineticsupply.com',
allScriptsTimeout:30000,
// Selector for the element housing the angular app - this defaults to
// body, but is necessary if ng-app is on a descendant of <body>
rootElement: 'body',
// A callback function called once protractor is ready and available, and
// before the specs are executed
// You can specify a file containing code to run by setting onPrepare to
// the filename string.
onPrepare: function () {
// At this point, global 'protractor' object will be set up, and jasmine
// will be available. For example, you can add a Jasmine reporter with:
// jasmine.getEnv().addReporter(new jasmine.JUnitXmlReporter(
// 'outputdir/', true, true));
},
// ----- Options to be passed to minijasminenode -----
jasmineNodeOpts: {
// onComplete will be called just before the driver quits.
onComplete: null,
// If true, display spec names.
isVerbose: true,
// If true, print colors to the terminal.
showColors: true,
// If true, include stack traces in failures.
includeStackTrace: true,
// Default time to wait in ms before a test fails.
defaultTimeoutInterval: 30000
}
};
<div id="sign-in-container">
<div id="sign-in">
<div class="logoContainer">
<!-- <img src="/assets/img/silpada_logo.png" style="display:block;padding:2rem 0;margin:auto;" alt=""> -->
<img ng-src="{{clientLogo}}" style="display:block;padding:2rem 0;margin:auto;" alt="">
</div>
<div ng-hide="catchResponses" alerts></div>
<form id="sign-in-form" name="authForm" ng-submit="login(credentials)">
<input
id="sign-in-account"
name="account"
type="text"
placeholder="Account ID"
ng-model="credentials.account"
required />
<input
id="sign-in-username"
name="username"
type="text"
placeholder="Username"
ng-model="credentials.username"
required />
<input
id="sign-in-password"
name="password"
type="password"
placeholder="Password"
ng-model="credentials.password"
required />
<button ng-disabled="authForm.$invalid || authenticating()" class="button-primary" type="submit">Login <i style="float:right; font-size:1.5rem;" class="fa fa-cog fa-spin" ng-show="authenticating()"></i></button>
<div id="reset-password">Forgot password?</div>
</form>
</div>

Here's my working script, just add ptor.ignoreSynchronization = true;
describe('Login', function () {
ptor = protractor.getInstance();
ptor.ignoreSynchronization = true;
beforeEach(function () {
// URL is relative to baseUrl specified in config/test/protractor-e2e.conf.js
ptor.get('/');
});
it('should redirect user to first module they have access to after successful login', function () {
// Should successfully register a user
ptor.findElement(protractor.By.name('account')).sendKeys('test');
ptor.findElement(protractor.By.name('username')).sendKeys('test#testing.com');
ptor.findElement(protractor.By.name('password')).sendKeys('1234');
ptor.findElement(protractor.By.css('.button-primary')).click();
// Should move to register page
expect(browser.getCurrentUrl()).toContain('silpada.kineticsupply.com/module/analytics');
// Should show the first name where the lock icon was
expect(element(by.name('account')).getText()).toContain('test');
});
});
My Running result
Using the selenium server at http://localhost:4444/wd/hub
Login
should redirect user to first module they have access to after successful lo
gin
Failures:
1) Login should redirect user to first module they have access to after succes
sful login
Message:
Expected 'http://silpada.kineticsupply.com/login' to contain 'silpada.kinet
icsupply.com/module/analytics'.
Stacktrace:
Error: Failed expectation
2) Login should redirect user to first module they have access to after succes
sful login
Message:
Expected '' to contain 'test'.
Stacktrace:
Error: Failed expectation
Finished in 12.697 seconds
1 test, 2 assertions, 2 failures

Related

How to perform beforeTest and afterTest method using typescript (protractor+cucumber)

Framework used - Protractor
BDD - Cucumber
Language - Typescript
Now i have implemented the framework and a test scenario is also running fine with protractor.
But the problem i am facing is when i write another cucumber scenario my test fails saying 'A session is either terminated or not started'
The above failure is because when my first cucumber scenario starts the appium server starts with in my config and at the end i close the server/driver
Now i have written another test scenario, since cucumber is independent of each scenario , when the sec starts it does not do the config again. Now i need a beforeTest method to call.
So i am not sure how to implement that in typescript,as i am new to it.
Tried the same concept of java way but not working out. There where examples for javascript but still did not help me out.
Tried creating a new util folder and placing my beforeTest inside that but the function is not calling there
Tried to use beforeLaunch()with in my config file, but still does not work out
my config file: config.ts
export let config: Config = {
allScriptsTimeout: 40000,
getPageTimeout: 40000,
setDefaultTimeout: 60000,
defaultTimeoutInterval: 30000,
specs: [
// '../../utils/beforeEach.ts',
'../../features/*.feature',
],
onPrepare: () => {
Reporter.createDirectory(jsonReports);
tsNode.register({
project: './tsconfig.json'
});
},
multiCapabilities: [
androidPixel2XLCapability,
// iPhoneXCapability
],
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
cucumberOpts: {
compiler: "ts:ts-node/register",
glue: ["steps"],
format: [
"json:./reports/json/cucumber_report.json",
],
require: ['supports/timeout.js', '../../stepdefinitions/*.ts'],
tags: "#firstPurchasePopup",
},
seleniumAddress: serverAddress,
onComplete: () => {
Reporter.createHTMLReport();
},
// =====
// Hooks
// =====
beforeTest: function () {
},
beforeLaunch(){
console.log("Before");
seleniumAddress: 'http://localhost:4723/wd/hub';
},
afterLaunch() {
console.log("After");
},
};
my other beforeEach.ts:
This is not working but what i tired and was not working.
import {After, AfterAll, Before} from "cucumber";
const serverAddress = 'http://localhost:4723/wd/hub';
import {beforeEach, afterEach, describe} from "selenium-webdriver/testing";
beforeEach(function () {
console.log("Before");
});
// });
afterEach(function () {
console.log("Before");
});
// let beforeEach: () => void;
// beforeEach = () => {
// console.log("Before Test");
// // config.multiCapabilities;
// seleniumAddress: serverAddress;
// };
//
// let afterEach: () => void;
// afterEach = () => {
// console.log("After Test");
// };
This is my feature file: bonus.feature
this is my feature file:
Background:
Given I launch the app
Then I should see the popup window for the Bonus
And I verify the UI
Then I tap on ok button
And The popup window should not be seen
#firstPurchasePopup
Scenario: firstPurchasePopup new join button
When I tap on the 'New ' button
And The popup window should not be seen
Then I navigate back from join page to home page
Then The popup window should not be seen
Then I close the app
#firstPurchasePopup
Scenario: firstPurchasePopup login button
And I tap on log in button on the initial screen
Then I navigate back from login page to home page
And The popup window should not be seen
Then I close the app
I expect my the scenario what i have written to execute both one after the other , like execute Scenario: firstPurchasePopup new join button which it does . But when it launches the app again for the sec Scenario: firstPurchasePopup login button does not work as the driver is not started again, since it was closed in prev one.
to start it i need to create beforeTest which i am facing difficutly to write the code
I haven't used Protractor with Cucumber, but I have used Cucumber & Typescript together. I resolved the problem by having a file cucumber.js in a root that is being loaded at the very beginning by default and looks like that:
var settings = "features/**/*.feature -r step-definitions/**/*.ts -r hooks/**/*.ts -r support/**/*.ts "
module.exports = {
"default": settings
}
However, I think in your case the solution would be adding a path to hooks file to config.cucumberOpts.require list instead to config.specs one.
Did you try it?
#All
Thanks for your inputs #mhyphenated
I figured out that the rather than using inside the config, i tried using the before and after in the hooks.ts ,also other than calling the server i was not actually calling the android driver, as below and that worked
beforeTest: function () {
beforeTest: function () {
},
beforeLaunch(){
console.log("Before");
seleniumAddress: 'http://localhost:4723/wd/hub';
},
hooks.ts
import { AndroidDriver } from "appium/node_modules/appium-android-driver";
let driver:AndroidDriver, defaultCaps;
driver = new AndroidDriver();
Before(function () {
// This hook will be executed before all scenarios
browser.ignoreSynchronization = false;
browser.manage().timeouts().implicitlyWait(500);
let defaultCaps = config.multiCapabilities[0];
console.log("defaultCaps = ", defaultCaps );
driver.createSession(defaultCaps);
driver.defaultWebviewName();
});

Load external js file, then immediately reference the created object [Vuejs2]

I'm loading the Paypal smart button into a vue component. I've tried loading the external Paypal js script, which appears to create a paypal object.
However when trying to access the paypal object, I get this error:
found in
---> <PaypalButton> at resources/assets/js/components/PaypalButton.vue
<Root>
After the page is loaded, I can successfully console.log(paypal) in chrome dev tools console window, and I can also successfully create a button in vue to also access it, but it does not appear to be able to referenced in the mounted hook.
Here is the code:
<template>
<div class="paypal-button-wrapper">
<div id="paypal-button-container"></div>
<button #click="showPaypal">Clicking this successfully renders the button</button>
</div>
</template>
<script>
export default {
data: () => ({
}),
mounted: function () {
let paypalScript = document.createElement('script');
paypalScript.setAttribute('src', 'https://www.paypal.com/sdk/js?client-id=AUo4kSgRdH44poEYLQwPdqM24oN8nQc4Jm1HAkWs5vQTAMGu-BBlpfN4xnMDEzSGfj4wjwOy6eLtNKyv&currency=USD');
document.head.appendChild(paypalScript);
this.showPaypal(); // fails to render the paypal button, with reference error
},
methods: {
showPaypal: function() {
paypal.Buttons().render('#paypal-button-container');
}
}
};
</script>
The solution is to use paypalScript.onload. I'm not sure if this is the most direct method, but it does work.
mounted: function () {
let paypalScript = document.createElement('script');
paypalScript.setAttribute('src', 'https://www.paypal.com/sdk/js?client-id=SB_ID&currency=USD');
document.head.appendChild(paypalScript);
var that = this;
paypalScript.onload = function () {
that.showPaypal();
};
},
Reference: Run the method of the Vue component after the external script is loaded

Freezing when signup using passport / express / mongodb

I'm working my way through a tutorial regarding passport.js and authentication and I'm coming unstuck. I'm just testing the signup function at the moment and my app is freezing. Here's my server file:
var express = require('express'),
app = express(),
mongoose = require('mongoose'),
passport = require('passport'),
flash = require('connect-flash'),
morgan = require('morgan'),
cookieParser = require('cookie-parser'),
bodyParser = require('body-parser'),
session = require('express-session');
// configDB = require('./config/database.js');
mongoose.connect('mongodb://localhost/Auth_practice');
require('./config/passport')(passport); // pass passport for config
// set up express app
app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (required for auth)
app.use(bodyParser()); // get information from html forms
app.set('view engine', 'ejs') // set up ejs for templating
// required for passport
app.use(session({secret: 'ilovethetoonandrafa'})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // for persistent login
sessions
app.use(flash());
// routes
require('./app/routes.js')(app, passport); // load our routes
and pass in passport
app.listen(process.env.PORT, process.env.IP, function(){
console.log("Server has started")
});
Here's my user model:
// load the things we need
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
// define schema for our user model
var userSchema = mongoose.Schema({
local :{
email : String,
password : String,
},
facebook :{
id : String,
token : String,
email : String,
name : String
},
twitter :{
id : String,
token : String,
displayName : String,
username : String
},
google :{
id : String,
token : String,
email : String,
name : String
}
});
// method =========================
// generate a hash
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// check if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);
My strategy setup:
// config/passport.js
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var User = require('../app/models/user');
// expose this function to our app using module.exports
module.exports = function(passport) {
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
};
And my route for signup
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/profile', // redirect to the secure profile of the
user
failureRedirect: '/signup', // redirect to signup page if failure
failureFlash: true // allow flash messages
}));
Finally here's the signup form:
<!-- views/signup.ejs -->
<!doctype html>
<html>
<head>
<title>Node Authentication</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> <!-- load bootstrap css -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> <!-- load fontawesome -->
<style>
body { padding-top:80px; }
</style>
</head>
<body>
<div class="container">
<div class="col-sm-6 col-sm-offset-3">
<h1><span class="fa fa-sign-in"></span> Signup</h1>
<!-- show any messages that come back with authentication -->
<% if (message.length > 0) { %>
<div class="alert alert-danger"><%= message %></div>
<% } %>
<!-- LOGIN FORM -->
<form action="/signup" method="post">
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-warning btn-lg">Signup</button>
</form>
<hr>
<p>Already have an account? Login</p>
<p>Or go home.</p>
</div>
</div>
</body>
Can anyone see what's causing the app to freeze?

How can i prevent User from directly accessing the HTML page

I have got a set 3 HTML Pages
I am using Apache Tomcat 7 server . I have got the following HTML pages (All are HTML pages only)
login.html
sales.html
index.html
The code for the login.html is when clicked on submit is
<input type="email" name="email" id="email" >
<input type="pin" name="email" id="pin" >
<button class="primary login-btn">Submit</button>
Once clicked on Submit button , i am calling a Jersey REST Webservce this way and will response either true OR false based on the values present in our Database
function submitLoginForm() {
var email_input = $.trim($("#email").val());
var pin_input = $.trim($("#pin").val());
var logininfo = {
'email': email_input,
'pin': pin_input
};
var login_information = JSON.stringify(logininfo);
$.ajax({
type: 'POST',
dataType: 'json',
data: login_information,
url: url + '/HEGS/orn/webchecklogin',
success: function(response) {
// if true , redirect to sales.html page
window.location = "index.html"
},
});
}
All this is working fine , my issue is , how can i stop the prevent the user from accessing the page directly
For example if he types the follwing URL
http:localhost:8080/HEGS/dealer/sales.html
You would want to redirect the url to one file, which would then load the correct file based on the criteria you set. I don't know much about Tomcat, but this article seems to explain it well under the "URL Rewriting" section.

Report accessibility plugin results

The protractor.conf file is configured to report the jasmine test results in junit format according to https://github.com/larrymyers/jasmine-reporters#protractor
// An example configuration file.
// https://raw.github.com/angular/protractor/master/example/conf.js
exports.config = {
// The address of a running selenium server.
// seleniumServerJar: './node_modules/protractor/selenium/selenium-server-standalone-2.41.0.jar', // Make use you check the version in the folder
//seleniumAddress: 'http://localhost:4444/wd/hub',
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
framework: "jasmine2",
onPrepare: function() {
var jasmineReporters = require('jasmine-reporters');
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
filePrefix: 'xmloutput',
savePath: 'testresults'
}));
},
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000
},
plugins: [{
chromeA11YDevTools: true,
path: 'node_modules/protractor/plugins/accessibility'
}]
};
Unfortunately it does not report the results from the accessibility plugin.
In the terminal i see:
Pass: Chrome A11Y - Audio elements should have controls
Pass: Chrome A11Y - ARIA state and property values must be valid
Pass: Chrome A11Y - Elements with ARIA roles must use a valid, non-abstract ARIA role
Fail: Chrome A11Y - Controls and media elements should have labels
2 elements failed:
<input type="checkbox" ng-model="todo.done" class="ng-pristine ng-untouched ng-valid">
<input type="checkbox" ng-model="todo.done" class="ng-pristine ng-untouched ng-valid">
https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#-ax_text_01--controls-and-media-elements-should-have-labels
How may this be achieved?
This is not possible with the plugin framework. The problem is that plugins are agnostic to the test framework being used, so they do not emit test results in a way specific to jasmine-reporters.
You can get all test and plugin results in JSON format using resultJsonOutputFile in the config. I'd suggest doing that, and then processing it in any way you need.