Protractor test chrome doesn't click on item while safari does - javascript

My test passes without problems in safari while in chrome this particular bit doesn't seem to work:
it('should click the first source and get to the source preview page', function () {
var grid_icon = element(by.css('.fa-th'));
var sources = element.all(by.repeater('source in shownSources'));
sources.get(0).element(by.tagName('a')).click();
browser.pause();
// Check url
expect(browser.getCurrentUrl()).toContain('/source/');
});
After clicking on the hyperlink it should change to a url containing "/source/". This works perfectly fine in Safari but in Chrome it fails
My protractor config file:
exports.config = {
framework: 'jasmine2',
seleniumServerJar: '../node_modules/protractor/selenium/selenium-server-standalone-2.45.0.jar',
seleniumPort: 4444,
troubleshoot: false,
basePath: '../',
specs: ['protractor/***/**/*.js'],
baseUrl: 'http://localhost:9000',
capabilities: {
browserName: 'chrome'
},
onPrepare: function() {
browser.manage().window().maximize();
}
};
Edit: My initial problem seems to not occur anymore. But the test still behaves very strange. This bit here works perfectly fine in Safari:
it('should add all sources to the list and show the cart icon on the source in inventory', function () {
browser.get('/sources');
var ordersources = element.all(by.repeater('orderSource in orderSources'));
var sources = element.all(by.repeater('source in shownSources'));
sources.get(0).element(by.css('a')).click();
var add_to_cart_btn = element(by.binding('addBtnText'));
add_to_cart_btn.click();
browser.get('/sources');
sources.get(1).element(by.css('a')).click();
var add_to_cart_btn = element(by.binding('addBtnText'));
add_to_cart_btn.click();
browser.get('/sources');
browser.pause();
sources.get(2).element(by.css('a')).click();
var add_to_cart_btn = element(by.binding('addBtnText'));
add_to_cart_btn.click();
browser.get('/sources');
expect(ordersources.count()).toBe(3);
sources.each(function (field) {
var isInCart_symbol = field.element(by.css('.fa-cart-arrow-down'));
expect(isInCart_symbol.getAttribute('aria-hidden')).toBe('false');
});
});
In Chrome however the 'a' item isn't found the second time and the browser.sleep() is never executed and the next 'it' begins to run.
EDIT: I got it to work by using a another html element by the class attribute.
element.(by.css('.example'))

I'm assumming that when you say it fails, the expect is failing? Here are 3 possible things you could try.
// Wait Till Url Contains
function WaitTillUrlContains(text, time, errMessage){
if(typeof(time) ==='undefined') time = 5000;
browser.getCurrentUrl().then(function (currentUrl) {
browser.wait(function () {
return browser.getCurrentUrl().then(function (newUrl) {
var test = newUrl;
if( test.indexOf(text) >= 0){
// Found word
return true;
}
});
}, time , errMessage);
});
};
(1) add a wait before the expect.
it('should click the first source and get to the source preview page', function () {
var grid_icon = element(by.css('.fa-th'));
var sources = element.all(by.repeater('source in shownSources'));
sources.get(0).element(by.tagName('a')).click();
// Check url
WaitTillUrlContains("/source/", 5000, "✗ Failed to wait for page to load");
expect(browser.getCurrentUrl()).toContain('/source/');
});
(2) do a .then() function after the click
it('should click the first source and get to the source preview page', function () {
var grid_icon = element(by.css('.fa-th'));
var sources = element.all(by.repeater('source in shownSources'));
sources.get(0).element(by.tagName('a')).click().then(function(){
// Check url
WaitTillUrlContains("/source/", 5000, "✗ Failed to wait for page to load");
expect(browser.getCurrentUrl()).toContain('/source/');
});
});
(3) do a .then() function after getting the element then do the click
it('should click the first source and get to the source preview page', function () {
var grid_icon = element(by.css('.fa-th'));
var sources = element.all(by.repeater('source in shownSources'));
sources.get(0).element(by.tagName('a')).then(function(elem){
elem.click();
// Check url
WaitTillUrlContains("/source/", 5000, "✗ Failed to wait for page to load");
expect(browser.getCurrentUrl()).toContain('/source/');
});
});

The reason why your link isn't found the second time is because you reload the page with browser.get(). After the reload, the sources handle is lost and webdriver doesn't know what element to operate on.
You either need to declare sources variable again after the page reload or avoid reloading the page.

Related

No success when trying to login on a page using Protractor: no error is pointed but the same page is loaded

I am beginner in using protractor. I am just trying to do a page logon in a non angular page. I tried many solutions/workarounds, the last one was based on the following link:
http://agiletesters.com.br/topic/71/protractor-page-objects-typeerror-object-object-has-no-method-metodo/7
Basically, i have two files: conf.js and login.js (see codes further). I execute the following command (in my prompt, os windows):
protractor conf.js
// Code conf.js =>
exports.config = {
framework: 'jasmine',
specs: ['login.js'],
directConnect: true
}
// Code login.js =>
describe('Protractor Demo App', function() {
browser.driver.ignoreSynchronization = true;
var originalTimeout;
beforeEach(function() {
browser.driver.ignoreSynchronization = true;
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
browser.driver.get('http://www.maisbolao.com.br');
});
afterEach(function() {
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
});
it('should fill user and password and logins', function() {
var loginNameInputElm = browser.driver.findElement(by.xpath('//*[#id="Email"]'));
var passwordInputElm = browser.driver.findElement(by.xpath('//*[#id="Senha"]'));
var loginBtnElm = browser.driver.findElement(by.xpath('//*[#id="form-login"]'));
loginNameInputElm.sendKeys('login');//i omitted the login and password information just for security reasons
passwordInputElm.sendKeys('password');
loginBtnElm.click();
});
it('reach?', function() {
console.log("browser.driver.getCurrentUrl(): "+browser.driver.getCurrentUrl());
browser.driver.sleep(5000);
});
});
I also tried to use the addCookie function with the JSESSIONID cookie value, but the same message below was displayed and the same behaviour observed.
The message protractor gives to me is:
There are some issue in your code:
it('reach?', function() {
browser.sleep(5000);
// sleep 5s to wait page load after click login button for debug purpose
// should replace to browser.wait()
browser.getCurrentUrl().then(function(url){
console.log("browser.driver.getCurrentUrl(): " + url);
});
// browser.getCurrentUrl() return a promise
// you should consume the eventual value of promise inside then()
browser.sleep(5000);
});
According to your screenshot there is some warnings but your 2 tests passed (2 specs 0 failures).
If your test fails you will have red F instead of green dot.

CasperJS or PhantomJS - how to export variable in-between functions?

With CasperJS or PhantomJS I want to:
1.) Visit 1 page and get Captcha image.
2.) Then decode Captcha on local server.
3.) Then submit the decoded Captcha results to 1. page.
4.) And get result (HTML).
A simple test assuming the Captcha code is 12345 to test that all values are entered and executed correctly like:
var casper = require('casper').create({ verbose: true, logLevel: "debug" });
var NUMBER_TO_CHECK = '356702087654321';
var DECODED_CAPTCHA = '12345';
casper.start('https://checkcoverage.apple.com/', function () {
this.sendKeys('input#serial-number', NUMBER_TO_CHECK);
this.sendKeys('input#captcha-input', DECODED_CAPTCHA);
this.mouseEvent('click', '.button-label', '50%', '50%');
this.wait(1000, function () {
this.echo('WAIT DONE');
});
});
casper.then(function (e) {
this.capture('logged-in.png');//print screen shot after click
});
casper.run();
This code snippet above gives Success result and says the given Captcha 12345 is incorrect which is true.
Now I need to modify this snippet so I can get the Captcha Image and process it on local server, and I have tried like:
var casper = require('casper').create({ verbose: true, logLevel: "debug" });
var NUMBER_TO_CHECK = '356702087654321';
casper.start('https://checkcoverage.apple.com/', function () {
this.sendKeys('input#serial-number', NUMBER_TO_CHECK);
// Get Encoded Captcha as Var
var captcha_encoded = casper.evaluate(function() {
return document.getElementsByClassName('captcha-image')[0].outerHTML;
});
// Post Encoded Captcha for decoding processing.
casper.then(function() { this.open('http://127.0.0.1/decode_captcha.php', {
method: 'post', data: { 'data': captcha_encoded } });
});
// Return Decoded Captch
casper.then(function() { var DECODED_CAPTCHA = this.getHTML('body');
this.echo(DECODED_CAPTCHA);
return(DECODED_CAPTCHA);
});
// How to Submit the Decoded Captcha result here ?
// Stuck here....
// ...
// this.sendKeys('input#captcha-input', DECODED_CAPTCHA);
// this.mouseEvent('click', '.button-label', '50%', '50%');
this.wait(1000, function () {
this.echo('WAIT DONE');
});
});
casper.then(function (e) {
this.capture('logged-in.png');//print screen shot after click
});
casper.run();
With this.echo(DECODED_CAPTCHA); I get the Decoded Captcha result in Console logs. But logged-in.png shows Screenshot from Local server, not from 1. page.
Question: How can I submit the var DECODED_CAPTCHA result to 1. page?
This is kind a delicate question. As per official documentation there is no support for parallel browsing
Is it possible to achieve parallel browsing using CasperJS?
And for your use case you need exactly that to keep your Captcha the same.
You can try examples posted in this group to see if it helps you.

Webdriver.io + Mocha - What am I doing wrong??

I am new to Mocha and Webdriver.io, so please excuse me if I am being stupid...
Here is my code -
// required libraries
var webdriverio = require('webdriverio'),
should = require('should');
// a test script block or suite
describe('Login to ND', function() {
// set timeout to 10 seconds
this.timeout(10000);
var driver = {};
// hook to run before tests
before( function () {
// load the driver for browser
driver = webdriverio.remote({ desiredCapabilities: {browserName: 'firefox'} });
return driver.init();
});
// a test spec - "specification"
it('should be load correct page and title', function () {
// load page, then call function()
return driver
.url('https://ND/ilogin.php3')
// get title, then pass title to function()
.getTitle().then( function (title) {
// verify title
(title).should.be.equal("NetDespatch Login");
// uncomment for console debug
console.log('Current Page Title: ' + title);
return driver.setValue("#userid", "user");
return driver.setValue("#password", "pass");
return driver.click("input[alt='Log in']");
});
});
// a "hook" to run after all tests in this block
after(function() {
return driver.end();
});
});
I can execute this with Mocha, and the test passes, even though it doesn't seem to do all of the "steps" I have defined..
It opens the page, logs the website title, and enters 'user' in the userid, BUT..
It doesn't populate the password field, or select the login link, and there doesn't appear to be any errors displayed..
Login to ND
Current Page Title: ND Login
✓ should be load correct page and title (2665ms)
1 passing (13s)
But, as it hasn't executed all the steps, I don't expect it to pass, though, I also don't understand why it won't do the last few steps.
Any help would be welcome.
Thanks
Karl
As mentioned in the original post comments, you should only have one return in your test:
it('should be load correct page and title', function () {
// load page, then call function()
return driver
.url('https://ND/ilogin.php3')
// get title, then pass title to function()
.getTitle().then( function (title) {
// verify title
(title).should.be.equal("NetDespatch Login");
// uncomment for console debug
console.log('Current Page Title: ' + title);
})
.setValue("#userid", "user")
.setValue("#password", "pass")
.click("input[alt='Log in']");
});

Protractor doesn't wait for redirect

I've got protractor's code written with Jasmine that is supposed to log in the user. Unfortunately there's a redirect going on after going to root url that takes quite some time (about 5 seconds) and I cannot make protractor wait for it. I've already tried browser.wait, I've tried using promises, I've tried with this blogpost, but nothing did it. It still doesn't wait. The login page is a page from Keycloak server, that's why I use driver.findElement instead of element. Here's my current code:
describe('my app', function() {
it('login', function() {
var driver = browser.driver;
browser.get('/');
console.log('get');
driver.findElement(by.id('username')).isPresent().then(function() {
console.log('waited');
driver.findElement(by.id('username')).sendKeys("test");
driver.findElement(by.id('password')).sendKeys("test");
driver.findElement(by.id('kc-login')).click();
driver.findElement(by.css('.page-header')).isPresent().then(function() {
console.log('ok');
expect(browser.getLocationAbsUrl()).toMatch("/test");
});
});
});
});
Do you know what can I do to make it work? I've started protractor project with this seed: https://github.com/angular/angular-seed
You need to turn the synchronization off:
var EC = protractor.ExpectedConditions;
describe('my app', function() {
beforeEach(function () {
browser.ignoreSynchronization = true;
browser.get('/');
});
it('login', function() {
var username = element(by.id('username'));
browser.wait(EC.visibilityOf(username), 10000);
username.sendKeys("test");
element(by.id('password')).sendKeys("test");
element(by.id('kc-login')).click();
var header = element(by.css('.page-header'));
browser.wait(EC.visibilityOf(header), 10000).then(function () {
console.log('logged in');
});
});
});
Note that I've also updated the test: switched back to element and browser, added browser.wait() with built-in Expected Conditions.

Jquery doesnt work on one of pages in app backbone.js

Im trying to do my first debug ever. The scenario is that there is a notification dropdown in the header, the dropdown opens but does not close on only one on the pages and works fine everywhere else in the app.The problem is that on one of the pages, the dropdown opens but doesn't close, my guess is the jquery to close down the button does not work. And I get the message:
Uncaught TypeError: Cannot read property 'el' of undefined.
When I put a breakpoint and call stacktrace above the line which has the error, for both working and not working pages, I compare the trace. I see, that if you take notice on the Call Stack on the right for the first image (which is the one that works), the last Call Stack is jQuery.event.add.elemData.handle and the one not working has just elemData.handle.
Not working page:
Working page:
relevant functions from the Call Stack:
class: notification_dropdown_view.js
app.views.NotificationDropdown = app.views.Base.extend({
events: {
"click #notifications-link": "toggleDropdown"
},
initialize: function(){
$(document.body).click($.proxy(this.hideDropdown, this));
this.notifications = [];
this.perPage = 5;
this.hasMoreNotifs = true;
this.badge = this.$el;
this.dropdown = $("#notification-dropdown");
this.dropdownNotifications = this.dropdown.find(".notifications");
this.ajaxLoader = this.dropdown.find(".ajax_loader");
this.perfectScrollbarInitialized = false;
},
....
etc etc
....
hideDropdown: function(evt){
var inDropdown = $(evt.target).parents().is($(".dropdown-menu", this.dropdown));
var inHovercard = $.contains(app.hovercard.el, evt.target);
if(!inDropdown && !inHovercard && this.dropdownShowing()){
this.dropdown.removeClass("dropdown-open");
this.destroyScrollbar();
}
}
toggleDropdown: function(evt){
evt.stopPropagation();
if (!$("#notifications-link .entypo-bell:visible").length) { return true; }
evt.preventDefault();
if(this.dropdownShowing()){ this.hideDropdown(evt); }
else{ this.showDropdown(); }
},
class: app.js:
setupGlobalViews: function() {
app.hovercard = new app.views.Hovercard();
$('.aspect_membership_dropdown').each(function(){
new app.views.AspectMembership({el: this});
});
app.sidebar = new app.views.Sidebar();
},
The two things that I always go to when dealing with dynamic states of elements that depend strictly on user interaction is the JavaScript setInterval() method or the jQuery on.('propertychange click input');

Categories

Resources