I'm trying to set up Protractor for testing my application but it requires auth through gmail, and I'm stuck on trying to login:
describe('Vivace Home page', function() {
var hasClass = function (element, cls) {
return element.getAttribute('class').then(function (classes) {
return classes.split(' ').indexOf(cls) !== -1;
});
};
beforeEach(function() {
browser.ignoreSynchronization = true;
browser.get('/');
var emailInput = browser.driver.findElement(by.id('Email'));
emailInput.sendKeys('paulG#gmail.com')
var nextButton = browser.driver.findElement(by.id('next'));
nextButton.click().then(function() {
browser.pause();
var passwordInput = browser.driver.findElement(by.id('Passwd'));
console.log(passwordInput);
passwordInput.sendKeys('11111');
// var signInButton = browser.driver.findElement(by.id('signIn'));
})
});
it('should have the correct title', function() {
expect(browser.getTitle()).toEqual('InRhythm - Vivace');
});
});
I can see Protractor opening up the gmail page, inputting the email and clicking the next button, and when I do browser.pause I can actually see the password input with an id of "Passwd" right there on the page with inspector and yet I can't access it to complete my log in.
I get this error when I remove the browser.pause
Failed: no such element: Unable to locate element: {"method":"id","selector":"Passwd"}
Wait for it to become visible:
var EC = protractor.ExpectedConditions;
var passwordInput = element(by.id('Passwd'));
browser.wait(EC.visibilityOf(passwordInput), 5000);
passwordInput.sendKeys('11111');
Related
using local storage and onclick with javascript
I have a html file with 2 job descriptions :
html file 1
<li><Job Reference Number: wru01</li>
<li><Job Reference Number: wru01</li>
I need to create a link (using javascript) that when each job description is clicked it auto fills out the form where the job description should be entered (this form is on another html page)
html file 2:
<legend>Job Application Information: </legend>
<label> Job Reference Number: </label>
<input id="refnumber" type="text" name="refnumber" required="required" />
so basically i need it that, when, and depending on which job number is clicked wru01 or wru02, it auto fills the job reference number in the form on the next page using local storage.
I have already tried this
js file 1
function onclick1() {
var anchor = document.getElementById('link');
anchor.addEventListener('click', function(event) {
event.preventDefault();
const jobCode = event.target.getAttribute('data-job');
localStorage.setItem('job-code', jobCode);
//need redirect user to apply page
//console.log(event.target)
window.location = event.target.getAttribute('href');
})
}
function onclick2() {
var anchor = document.getElementById('link2');
anchor.addEventListener('click', function(event) {
event.preventDefault();
const jobCode = event.target.getAttribute('data-job');
localStorage.setItem('job-code', jobCode);
//need redirect user to apply page
//console.log(event.target)
window.location = event.target.getAttribute('href');
})
}
function init() {
document.getElementById("link").onclick = function() {
onclick1()
};
document.getElementById("link2").onclick = function() {
onclick2()
}
window.onload = init;
}
js file 2
function LoadJobCode() {
var code = localStorage.getItem('job-code');
if (code) {
var input = document.getElementById('refnumber');
// disable text being entered
input.value = code;
input.disabled = true;
}
}
Excuse me,that's not a good idea to do it.I think you can use setTimeout to solve the problem.that's my code:
function onclick1() {
var anchor = document.getElementById('link');
anchor.addEventListener('click', function (event) {
event.preventDefault();
const jobCode = event.target.getAttribute('data-job');
console.log(jobCode)
localStorage.setItem('job-code', jobCode);
setTimeout(() => {
window.location.href = event.target.getAttribute('href');
},1000)
})
}
why did I do that?That's order to make sure to save the data(data-job) before entering another html page.Likewise,you can use async/await,such as below:
function onclick1() {
var anchor = document.getElementById('link');
anchor.addEventListener('click', function (event) {
event.preventDefault();
const jobCode = event.target.getAttribute('data-job');
console.log(jobCode)
localStorage.setItem('job-code', jobCode);
async function locate() {
await new Promise(() => {
window.location.href = event.target.getAttribute('href');
})
}
locate();
})
}
My protractor script not picking up element on next page. It runs the test on the first page (filling in customers details). Upon clicking to redirect, cmd fires;
Failed: No element found using locator: by.model("formData.card_no")
Is it because angular is not loading or must I inject $scope.
I'm new to protractor. Tried all sorts of waits and sleeps on the driver.. plus ignoreSynchronisation.. nothing.
However when I manually place the generated ID at the end of the payment details' url, it picks up all the elements and all tests are passed.
So the problem must be with fetching the seller's generated transaction ID from the backend to continue with test. Not certain how it's done in Protractor.
conf.js
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
capabilities: {
'browserName': 'chrome'
},
pecs: ['../test/*spec.js'],
jasmineNodeOpts: {
showColors: true,
defaultTimeoutOutInterval: 30000
}
};
todo-spec.js
var util = require ('util');
describe('angularjs homepage todo list', function() {
browser.get('https://xxx');
element(by.css('.start-btn')).click();
var seller_details = require('../page/seller_details.js');
it ('should be bla bla bla', function(){
seller_details.enterFormName();
seller_details.enterFormCell();
seller_details.enterFormEmail();
seller_details.enterFormVR();
seller_details.enterFormVV();
seller_details.checkFormNotStolen();
seller_details.clickStart();
//after redirecting to payment details page
payment_details.enterCardNo();
payment_details.enterCardHolder();
payment_details.enterExpiryMonth();
payment_details.enterExpiryYear();
payment_details.enterCVV();
});
});
seller_details.js (page object)
require ('../page/payment_details.js')
var seller_details = function(){
this.enterFormName = function(value){
element(by.model('formData.name')).sendKeys('ron');
};
this.enterFormCell = function(value){
element(by.model('formData.cell')).sendKeys('0734555543');
};
this.enterFormEmail = function(value){
element(by.model('formData.email')).sendKeys('ron#sqw.com');
};
this.enterFormVR = function(value){
element(by.model('formData.veh_reg')).sendKeys('ND 3491');
};
this.enterFormVV = function(value){
element(by.model('formData.veh_vin')).sendKeys('13ADFPORT4QP9CR5L');
};
this.checkFormNotStolen = function(){
element(by.model('formData.not_stolen')).isSelected();
};
this.clickStart = function(){
element(by.css('.spinner-btn')).click();
return require('./payment_details.js');
};
};
module.exports = new seller_details();
payment-details.js (another page object)
var payment_details = function(){
this.enterCardNo = function(value){
element(by.model('formData.card_no')).sendKeys('4111111111111111');
};
this.enterCardHolder = function(value){
element(by.model('formData.card_holder')).sendKeys('yayayay');
};
this.enterExpiryMonth = function(value){
element(by.model('formData.expiry_month')).sendKeys('12');
};
this.enterExpiryYear = function(value){
element(by.model('formData.expiry_year')).sendKeys('2019');
};
this.enterCVV = function(value){
element(by.model('formData.cvv')).sendKeys('123');
};
this.clickBtn = function(value){
element(by.css('.spinner-btn')).click();
};
};
module.exports = new payment_details();
Thanks in advance for any help rendered. Let me know if you need controller.js which has the $scope.
The problem that I have with this test is that sometimes it passes, sometimes it fails, and when it does the latter a "Failed: No element found using locator: By(css selector, .add.create_ServiceOrders)" message appears in the console. Idk what to do to fix it :(
describe('angularjs homepage', function() {
it('should greet the named user', function() {
//browser.ignoreSynchronization = true
browser.get('https://int.m-tech.com/hotsosmobile/app/Index?/login#/login');
browser.waitForAngular();
var input = element(by.model('loginInfo.login'));
input.sendKeys('xxx');
expect(input.getAttribute('value')).toBe('xxx');
var input = element(by.model('loginInfo.password'));
input.sendKeys('yyy');
expect(input.getAttribute('value')).toBe('yyy');
browser.waitForAngular();
browser.driver.actions().sendKeys(protractor.Key.ENTER).perform();
browser.waitForAngular();
var AddButton = element(by.css(".add.create_ServiceOrders" ));
browser.actions().mouseDown(AddButton).mouseUp().perform();
browser.actions().mouseMove(AddButton).click().perform();
browser.waitForAngular();
var AddButton = element(by.css(".icon-standard-issue-floors" ));
browser.actions().mouseDown(AddButton).mouseUp().perform();
browser.actions().mouseMove(AddButton).click().perform();
browser.waitForAngular();
.....
});
});
Base on my experience, I usually do separate it in another it function something like this.
var AddButton = element(by.css(".add.create_ServiceOrders" ));
it ( 'should pass', function () {
browser.actions().mouseDown(AddButton).mouseUp().perform();
});
it ( 'should pass', function () {
browser.actions().mouseMove(AddButton).click().perform();
});
You need to wait for element to be ready, before manipulating. Try this:
var AddButton = $(".add.create_ServiceOrders");
browser.wait(protractor.ExpectedConditions.visibilityOf(AddButton), 5000, 'Button should be visible');
browser.actions().mouseDown(AddButton).mouseUp().perform();
browser.actions().mouseMove(AddButton).click().perform();
...
I am attempting to create script that will automate sign in process (to login). However, when I run script it says that 'could not be tapped'. Below is what I have written so far:
var target = UIATarget.localTarget();
var app = target.frontMostApp();
var appWindow = app.mainWindow();
var settingsButton = appWindow.buttons()["CloseVector"];
var settingsView = app.mainWindow().staticTexts()["Settings"]
UIALogger.logStart("Sign in test")
settingsButton.tap();
target.delay(1);
if (settingsView.isValid())
{
UIALogger.logPass("Correct View");
}
else
{
UIALogger.logFail("Wrong View");
}
function UsersVM(start_page){
var self = this;
console.log('start form ' + start_page);
self.go_to = function(page) {
location.hash = '#Users/' + pageNumber;
}
}
Sammy(function() {
this.get('/app/?#Users/:page', function () {
var vm = new UsersVM(this.params.page);
ko.applyBinding(vm);
});
}).run();
I would like to change the page's hash with the following code:
location.hash = '#Users/' + pageNumber;
But in this case Sammy triggers routing. Say in Backbone we can do it this way:
app.navigate("help/troubleshooting", {trigger: false});
Is it possible to do it in Sammy?
Thanks!
I don't know of a native way to do this in Sammy, but here is a solution that has worked for me:
var sam = $.sammy(function () {
var sammy = this; //get a persistent reference to this
sammy.quiet = false; //set quiet to false by default
//I set quiet to true before running a route
sammy.quietRoute = function (location) {
sammy.quiet = true;
sammy.setLocation(location);
}
//I'm called after every route to reset quiet to false
sammy.after(function () {
sammy.quiet = false;
});
//I'm a 'normal' route that does not have the capability to be 'quiet'
this.get('#normalRoute', function () {
//routing code
});
//I am a route that can be 'quieted' so that when the url or
//hash changes my routing code doesn't run
this.get('#quietableRoute', function () {
if (!sammy.quiet) {
//routing code
} else {
return;
}
});
});
Then call the quietRoute function in your code:
//This will work
sam.quietRoute("#quietableRoute");
//This will not work because the "if(!sammy.quiet)..." code has not been
//implemented on this route
sam.quietRoute("#normalRoute");
Use the following code:
var new_location = '#foo';
app.trigger('redirect', {to: new_location});
app.last_location = ['get', new_location];
app.setLocation(new_location);