Protractor-cucumber: chai.expect does not work - protractor

In Steps definition, i declare 'chai' and use to debug:
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
chai.usexpece(chaiAsPromised);
var expect = chai.expect;
module.exports = function() {
this.Given(/^I go on "([^"]*)"$/, function (arg1, callback) {
browser.driver.get(arg1);
browser.manage().timeouts().pageLoadTimeout(10000);
var answer = 43;
expect(answer).to.equal(42);
console.log("this text will be displayed");
callback();
});
}
When i run the script, text this text will be displayed does not appear ,in console but when i comment this line //expect(answer).to.equal(42);, the text appear as normal.
I know there is a wrong in expect of chai object but cannot find out the solution. Anyone can help me to resolve the issue. Thank so much

cucumber-js supports steps that return promises.
When using chai-as-promised, i need to return the expectation (which is a promise)
this.When(/^I test async code$/,function() {
return expect(true).to.be.true;
});

Related

Changed values are lost after returning from promise

I am doing E2E Test with protractor, using cucumber for test scenarios.
I face a strange problem: I lost the values I set inside of the promise.
What am I doing wrong?
My step-file.js:
var loggedUser = new User("dummyname", "dummyrole");
this.When(/^I click on a user name$/, function(){
userelem.element(by.className('username')).getText().then(function (txt) {
loggedUser.username = txt;
});
});
this.Then(/^The username of the object "loggedUser" is set to a new value$/, function(){
var answer = "dummyname" != loggedUser.username;
assert.isOk(answer, "username is still dummyname!"); //this line fails since usrname is set back to dummyname again!
});
Thank you #yong for your suggestion on my first post (which I have deleted meanwhile). Finally I understood what you meant. Here is the solution:
(Instead of upgrading to cucumber 2,) I "return" the promise from within the "When-Step", so that protractor waits until it is fullfilled before it executes the next step-function:
var loggedUser = new User("dummyname", "dummyrole");
this.When(/^I click on a user name$/, function(){
return userelem.element(by.className('username')).getText().then(function (txt) {
loggedUser.username = txt;
});
});
Now in the next step-functions, the username is the updated username.
The root cause is you need to make each step definition return a promise, I write a simple code for you and it worked well.
Make step definition return a promise is the key point.
For Cucumber 2:
var { defineSupportCode } = require("cucumber");
defineSupportCode(function({ Given, When, Then }) {
let title = 'test';
Given(/^open npmjs.com$/, function() {
browser.get("http://www.npmjs.com");
return browser.getTitle().then(function(title1){
title = title1;
console.log('title: ' + title);
});
});
Then(/^verify page title$/, function() {
return expect(title).to.equal('npm');
});
});
For Cucumber 1:
module.exports = function() {
let title = 'test';
this.Given(/^open npmjs.com$/, function() {
browser.get("http://www.npmjs.com");
return browser.getTitle().then(function(title1){
title = title1;
console.log('title: ' + title);
});
});
this.Then(/^verify page title$/, function() {
return expect(title).to.equal('npm');
});
};

Protractor - Unable to switch to twitter authorization pop-up from my angular js application

I am using Page object model where I am calling the below function written in a page_object.js from my spec. I have tried all possible ways but it always fails on switch. Please help
var Twitter_Actions = function (){
this.authorizeAccount = function(username,pswd){
browser.ignoreSynchronization = true;
return browser.getAllWindowHandles().then(function (handles) {
var popUpHandle = handles[1];
expect(popUpHandle).toBeDefined();// Asrton to cnfrm pop-up is defined
browser.switchTo().window(popUpHandle); // Failing on Switch
var windowtitle = browser.getTitle().then(function(webpagetitle){
return webpagetitle;
});
console.log(windowtitle);// Printing title on the console to debug
browser.executeScript('window.focus();');
element(by.name("session[username_or_email]")).sendKeys(username);
element(by.name("session[password]")).sendKeys(pswd);
element(by.id('allow')).click();
});
}
}

Protractor how to wait for options

I have code like this:
element(by.model("roleSelection.role")).element(by.cssContainingText('option', newRole)).click();//.then(function() {console.log('role click')})//;
where the options is loaded via a call to the server.
I can wait for the first element by doing this
browser.wait(function() {
return browser.isElementPresent(by.model("roleSelection.role")).then(function(present){
return present;
});}, 8000);
and it seems to work. But how can I wait until the "sub-element" is clickable.
I have tried this
browser.wait(function() {
return browser.isElementPresent(by.model("roleSelection.role")).then(function(present){
if (present) {
var elm = element(by.model("roleSelection.role"));
return elm.isElementPresent(by.cssContainingText('option', newRole)).then(function(subpresent) {
return subpresent;
});
}
}); }, 8000);
Have you tried clickable? Something along these lines
var EC = protractor.ExpectedConditions;
var select = element(by.model("roleSelection.role"))
var isClickable = EC.elementToBeClickable(select);
browser.wait(isClickable,5000); //now options should have been loaded by now
Well, try to this: https://angular.github.io/protractor/#/api?view=ExpectedConditions.prototype.elementToBeClickable
But, Please keep in mind, Protractor is suitable for angular webpages and interactions, and animations. For example ng-animate. So, it is not sure to working for example jquery, or other animates.
In this way:
onPrepare: function () {
// disable animations when testing to speed things up
var disableNgAnimate = function () {
angular.module('disableNgAnimate', []).run(function ($animate) {
$animate.enabled(false);
});
};
browser.addMockModule('disableNgAnimate', disableNgAnimate);
}
Or you can switch in script way in browser.executeScript().
Please see this link. It works only jquery animations.
If you not have animate problems. Use setTimeout() JS function.

Protractor : wait for element to become invisible/hidden

I saw other protractor related post mentioning about how to wait for an element to become visible. However, recently, I ran into an opposite use case. I wanted to wait for an element until it becomes invisible. Since I could not find anything specific about it. I went ahead and came up with a solution.
var ptor = protractor.getInstance();
ptor.wait(function() {
return element(by.css('#my-css-here')).isDisplayed().then(function(isVisible){
console.log('is visible :' + isVisible);
return !isVisible;
});
}, 12000).then(function(){
//do whatever you want
});
hopefully it helps. any suggestion is welcome.
Thanks,
Using the elementexplorer (https://github.com/angular/protractor/blob/master/docs/debugging.md) I looked at the protractor object and found an answer that is working wonderfully for me:
var el = element(by.id('visibleElementId'));
browser.driver.wait(protractor.until.elementIsNotVisible(el));
From #Machtyn
This should be the correct answer:
var EC=protractor.ExpectedConditions; browser.wait(EC.not(EC.presenceOf(el)), someTimeoutInMilli);
Protractor now has invisibilityOf function built in.
var EC = protractor.ExpectedConditions;
// Waits for the element with id 'abc' to be no longer visible on the dom.
browser.wait(EC.invisibilityOf($('#abc')), 5000);
Read more for details
None of the solution working for me. Please take a look at below code:
var protractor = require('protractor');
describe('Testing', function () {
it('Should show the settings button', function () {
var EC = protractor.ExpectedConditions;
var settings = $('.settings');
var isSettingVisible = EC.visibilityOf(settings);
browser.get('http://localhost:8080/#/edomonitor');
console.log("--------------------welcome 1-------------------");
protractor.browser.wait(isSettingVisible, 10000, "Searching for settings").then(() => {
console.log("waiting complete");
}, (error) => {
console.log(error);
})
expect(2).toEqual(2);
});
});

TERROR MOVIE: Error while waiting for Protractor to sync with the page: {} VOL VIII

I've been checking others threads about this common error and trying to apply what they recommend but still getting same error. I warn you I'm totally newbie at PROTRACTOR.
This it's the first test I'm writting:
describe('Just some shitty test', function(){
'use strict';
it('Testing some shitty test', function(){
beforeEach(function () {
browser.get(browser.baseUrl);
});
/*
Purpose:
1. Getting in "HEALTH CARE PARTNER / ORGANISATION (KND. NR.: 438)" panel
2. Edit content
3. Save it
*/
// First, I find elements I want to test
//ANCHOR Bearbeiten
var $a = $('a','div.m-pane__control');
//INPUT Name
var $name = $('input[placeholder="Name"]');
//SELECT
var $select = $('select','m-form__select ng-scope');
//INPUT Yearly births
var $yearly = $('input[placeholder="Yearly births"]');
//INPUT Homepage
var $homepage = $('input[placeholder="Homepage"]');
//INPUT Email
var $email = $('input[placeholder="Email"]');
//TEXTAREA. two ways to find it
var $textarea1 = $('textarea[ng-model="model[field.name]"]');
var $textarea2 = element(by.model('model[field.name]'));
//BUTTON Speichern
var $speichern = $('button[ng-click="savebtn()"]');
// Sequence of actions
//Is bearbeiten button displayed?
//expect($a.isDisplayed()).toBe(true);
//Click on it!
//$a.click();
//Settings
//$name.sendKeys('John Smith').submit();
//$yearly.sendKeys('42');
//$homepage.sendKeys('something');
//$email.sendKeys('tschues#baba.at');
//$textarea1.sendKeys('fahren lassen');
//Save
//$speichern.click(); });});
I don't know if elements I've searched are ok but every time I call getText() function or either as click(), sendKeys or whatever, I always get Error while waiting for Protractor to sync with the page: {}.
What I'm forgetting or doing wrong?
Thank you
Try something like this
describe('Just some test', function(){
var ptor;
beforeEach(function () {
browser.get(browser.baseUrl);
ptor = protractor.getInstance();
ptor.waitForAngular();
});
it('should do something', function(){
var aLink = element(by.css('div.m-pane__control'));
aLink.click();
});
});
Biggest differences are I ask protractor to wait for angular, since it takes some time to get ready and I used the protractor style of finding elements on the page.