Auth login test using protractor and Azure AD - angularjs

I am trying to authnticate user with an e2e test. I am not able to get this working. The test never waits after the button click on Azure AD login page.
describe('angularjs homepage', function() {
var ptor = protractor.getInstance();
ptor.ignoreSynchronization = true;
it('should greet the named user', function() {
var driver = ptor.driver;
browser.driver.manage().window().setSize(1500, 1000);
browser.driver.get('https://test.azurewebsites.net/test-ui/');
driver.findElement(By.id("cred_userid_inputtext")).sendKeys("TestUser#test.onmicrosoft.com");
// Find the element that's ID attribute is 'pwd' (Password)
// Enter Password on the element found by the above desc.
driver.findElement(By.id("cred_password_inputtext")).sendKeys("23423421asdasd");
// Now submit the form. WebDriver will find the form for us from the element
ptor.findElement(By.id("cred_sign_in_button")).click();
browser.driver.sleep(50000);
expect(element(by.id('username')).getText()).toEqual("Test User");
});
Kindly help

I was able to login by clicking the button from waiting for loading after fill in the form.
driver.findElement(By.id("cred_password_inputtext")).sendKeys("23423421asdasd");
browser.driver.sleep(2000);
ptor.findElement(By.id("cred_sign_in_button")).click();

I figured out that the Azure AD login page needs are double click for the button. hence
var btn = ptor.findElement(By.id("cred_sign_in_button"));
btn.click();
btn.click();
worked for me.

Related

Jasmine - Restart browser between tests (it blocks)

In our Protractor+Jasmine framework trying to restart browser between tests for different login user. As we have non-angular login page and after login its navigate to angular page. Following is my main test spec file
describe('User Permissions', function() {
var docsLoginPage = require('../pages/CLM_Page.js');
var projectsPage = require('../pages/Projects_Page.js');
var contentPage = require('../pages/Content_Page.js');
beforeEach(function() {
browser.ignoreSynchronization = true;
browser.get('http://be-docs-dev.xyz.local/');
});
it('Verify permissions for Non Admin and Read only permission group user', function() {
docsLoginPage.loginToDocs("sipqa4#xyz.com","Yahoo#123");
expect(browser.getTitle()).toEqual('abc');
browser.ignoreSynchronization = false;
expect(projectsPage.checkElementExistsById('headers_nav_projects')).toBe(false);
expect(contentPage.checkElementExistsById("content_browse_options_folder_settings")).toBe(false);
expect(contentPage.checkElementExistsById('content_browse_options_new_menu')).toBe(false);
});
it('Verify permissions for Project collaborator Non Admin and Read only permission group user', function() {
/*browser.restart().then(function(){
console.log("-----------Restarted the browser---------------");
});*/
docsLoginPage.loginToDocs("sipqa2#xyz.com","Yahoo#123");
expect(browser.getTitle()).toEqual('abc');
browser.ignoreSynchronization = false;
expect(projectsPage.checkElementExistsById('headers_nav_content')).toBe(false);
expect(contentPage.checkElementExistsById("projects_browse_options_folder_settings")).toBe(false);
expect(contentPage.checkElementExistsById('projects_browse_options_new_menu')).toBe(false);
});
});
And CLM_Page.js
var CLM_page = function() {
this.userName = element(By.id('userName'));
this.password = element(By.id('password'));
this.signIn = element(By.className('btn btn-primary'));
this.loginToDocs = function(userName, password) {
browser.driver.manage().window().maximize();
browser.driver.manage().timeouts().implicitlyWait(10000);
this.userName.sendKeys(userName);
this.signIn.click();
this.password.sendKeys(password);
return this.signIn.click();
};
};
module.exports = new CLM_page();
In conf file set to
restartBrowserBetweenTests: true
First it block is executing correctly. However while executing second it block browser restarting and closing immediately. Showing following error
Failures:
1) User Permissions Verify permissions for Project collaborator Non Admin and Read only permission group user
Message:
Failed: This driver instance does not have a valid session ID (did you call WebDriver.quit()?) and may no longer be used.
Stack:
NoSuchSessionError: This driver instance does not have a valid session ID (did you call WebDriver.quit()?) and may no longer be used.
The problem here is the webdriver session is closed after starting the test.
There is no problem with restartBrowserBetweenTests: true, Since your browser is restarted after the first test.
Since you are moving from non angular to angular application. Follow as below
browser.driver.get('http://localhost:8000/login.html');
browser.driver.findElement(by.id('username')).sendKeys('Jane');
browser.driver.findElement(by.id('password')).sendKeys('1234');
browser.driver.findElement(by.id('clickme')).click();
You are using browser.ignoreSynchronization = true; which is deprectaed. Try usingwaitForAngularEnabled(true).
make the BeforEach() as
beforeEach(function() {
browser.waitForAngularEnabled(false); // to tell protractor that this is a non- anularg page
browser.get('http://be-docs-dev.xyz.local/');
});
After moving to angular page make it as browser.waitForAngularEnabled(true);.
Hope the above answer helps you...
Based on your test case design, you can achieve the same by setting restartBrowserBetweenTests: false in conf.js file
And also clear the browser cookies and session from the browser after each it block run. Please modify your existing test script by adding afterEach
add the below snippet with existing code
afterEach(function () {
browser.manage().deleteAllCookies();
browser.executeScript('window.sessionStorage.clear();window.localStorage.clear();');
});
beforeEach function should be like
beforeEach(function() {
browser.waitForAngularEnabled(false);
browser.get('http://be-docs-dev.xyz.local/');
});
In conf.js.
Note: Default value is false. So it is not mandatory to set it as false
exports.config = {
...
restartBrowserBetweenTests: false,
...
}
If you are setting restartBrowserBetweenTests: true, This will cause your tests to slow down drastically. Please refer this

How delete refresh login in after logout in angularjs

my logout function works (we display login page), but when i click on button disconnect the login page will be displayed but it will refresh 2 times.
how to fix this error to display login page without refresh
here is my function:
var _logOut = function () {
localStorageService.remove('authorizationData');
$state.go("login", {}, { reload: true });
$window.location.reload();
// _authentication.isAuth = true;
};
I don't think that $window.location.reload() is necessary.
Try removing it.

Make sure that back button won't navigate to signup page once signup was success?

In my ionic mobile app. I have signup page. Once a user's signup is success user will be navigated to profile page. Now what i want, once user is successfully signed up, users are not allowed to get back to signup page.
How can I make sure that back button won't navigate to signup page once signup was success ?
One solution I have is, to check for some condition every time signup page is loaded and based on that condition stay or navigate to other page. e.g.
if(userIsLoggedin()) {
$state.go('home')
}
Create a factory to store data
module.factory('DataStore', [function () {
var _local = {}, dataStore = {};
dataStore.setValue = function (field, value) {
_local[field] = value;
};
dataStore.getValue = function (field) {
return _local[field] || null;
};
return dataStore;
}])
Then once you validate that the user is registered you set the flag in DataStore
module.controller('registration', function(..., DataStore) {
...
//do all necessary logic
if(allGood) {
DataStore.setValue('RegistrationSuccessful', true);
}
});
Then anytime you can check from any other controller that imports DataStore
module.controller('home', function(..., DataStore) {
...
//do all necessary logic according to the code in your question
$scope.onbtnclick = function () {
if(DataStore.getValue('RegistrationSuccessful')) {
$state.go('home')
} else {
$state.go('registration');
}
};
});
You can do this by handling back button in ionic app. Check the app state on back button click if it's on profile page then do nothing so it will prevent default back event.
$ionicPlatform.registerBackButtonAction(function (event) {
if($state.current.name!="menu.profile" ){
$ionicHistory.goBack(-1);
}else{
// if state is profile then control will be here.
}
}, 100);
Put this code in app.js file.
Other suggestion: once user is register and login in to profile then he or she should be taken to profile page directly on app start.
you can do this in your register or verification function if user is not register then take it to signup page. and if user is logged in the take it to profile page.
Your solution looks good. I think you may also want to make sure you check the user session on the server side.

Use protractor on an non angular page

in my recent test I need to first login and take some actions on an non angular page (https://www.qa.dealertrack.com/default1.aspx)
then switch to an angular page and finish the test.
In conf I have
global.driver = browser.driver;
My page object looks like:
var LogInPage = function() {
this.loginUrl = 'https://www.qa.dealertrack.com/default1.aspx';
this.id = browser.driver.findElement(by.name('username'));
this.password = browser.driver.findElement(by.name('password'));
this.loginButton = browser.driver.findElement(by.name('login'));
this.logIn = function(id, password) {
// maximize window
driver.manage().window().maximize();
// log in
driver.get('https://www.qa.dealertrack.com/default1.aspx');
this.id.sendKeys(id);
this.password.sendKeys(password);
this.loginButton.click();
}
};
My test looks like:
describe('Sample Test - Log In', function() {
var loginPage = require('../pages/LogInPage.js');
/**
* Disable waiting for AngularJS for none Angular page
*/
beforeEach(function() {
isAngularSite(false);
});
it('logging in', function() {
loginPage.logIn('xxx', 'xxx');
})
})
However, even before getting to the site, protractor throws error NoSuchElementError: no such element: Unable to locate element:{'method':'name','selector':'username'}
But when I commented out all the element variables and related lines, only left
driver.get(this/loginUrl);
It worked. Why would browser.driver.get works but browser.driver.findElement does not?
This is my first question on Stackoverflow. Thank everyone!!
Before login you need to set
browser.driver.ignoreSynchronization=true;
So it shold be like
browser.driver.ignoreSynchronization=true;
login();
browser.driver.ignoreSynchronization=false;
I tried to removed all the elements I declared outside my functions in page object. Instead of that, I just hard code the elements in the function. And it worked.

Angular.js edit in place with password

This is my example here
I want to add password protect, when i click to "Edit title".
How can i do it?
JS code:
function ClickToEditCtrl($scope) {
$scope.title = "Welcome to this demo!";
$scope.editorEnabled = false;
$scope.enableEditor = function() {
$scope.editorEnabled = true;
$scope.editableTitle = $scope.title;
};
$scope.disableEditor = function() {
$scope.editorEnabled = false;
};
$scope.save = function() {
$scope.title = $scope.editableTitle;
$scope.disableEditor();
};
}
Simply create a $scope.checkPassword (or something meaningful) function which shows a popup/modal/etc where the user can input the password and then make an ajax call to verify for the password. If the password entered is correct enable editor else do nothing. Or maybe you want to allow save password if the user authenticates successfully.
UPDATE:
I think password verification should be handled totally by the server. I would make a call to function that handles authentication before saving the password (on the server). So make sure that you send the password as a parameter with the save call.

Resources