Stop testing after specific failures - angularjs

I have unpredictable behavior page that depends on changes that create developers. And sometimes my tests failed, because page wasn't load. My test scenario structure looks like:
describe('0. first actions', function () {
var lib = require("../../common.js");
var config = browser.params;
var url = config.listOfReferencesUrl, toolbar;
load(url, "list-of-references");
beforeAll(function () {
// some actions on the page
});
it('test0', function () {
since('test0 failed').
expect(toolbar.isPresent()).toBe(true);
});
describe('1.actions1', function () {
beforeAll(function () {
// some actions on the page
});
it('test1', function () {
since('test1 failed').
expect(table.getRow(clientNameNum).getRowInput().isEnabled()).toBe(true);
});
// ... another invested describes
});
Where load function is:
global.load = function (url, pageType) {
browser.get(url);
if (pageType == 'list-of-references'){
browser.executeScript("icms.go('WEB_INQ_PROC', 'InquiryList', null, 0)");
}
browser.waitForAngular();
};
I wonder if I can create structure to stop my tests if page isn't load. But I don't want to use 'jasmine-bail-fast', because I want to see another failures if page will load.
I tried to write something like:
if (this.results_.failedCount > 0) {
// Hack: Quit by filtering upcoming tests
this.env.specFilter = function(spec) {
return false;
};
}
But it isn't working. I use jasmine2.
Maybe somebody know how I can organize it?

You can define a wrapper
var filter = function (fn) {
if (!condition)
throw new Error('skipped');
return fn;
}
and use it on all relevant describe/it blocks:
describe('...', filter(function () {
...
}));

Related

Angular 1.x and AG-Grid Components

I'm trying to upgrade our app from a really old version to the latest (v16). Since they have deprecated the old way of cell and header renders I'm trying to wrap my head around using scope and Angular compilation.
The ag-grid documentation states: You will then need to manage creating and destroying child scopes yourself inside the init() and destroy() methods.
angularCompileRows, angularCompileFilters and angularCompileHeaders are not supported within Components.
I tried to create a cell render like this:
function MyCellRenderer() {
}
MyCellRenderer.prototype.init = function (params) {
$scope.myMessage = 'Hi Scott';
var compiled = $compile('<p ng-bind="myMessage"></p>')($scope);
this.eGui = document.createElement('span');
this.eGui.innerHTML = compiled.html();
};
MyCellRenderer.prototype.getGui = function () {
return this.eGui;
};
However this doesn't work. Any thoughts?
I was able to get this to work, but I don't like that I need to wrap around a $timeout. I had to do this because a digest was already in progress:
function MyCellRendererSimple() {
}
MyCellRendererSimple.prototype.init = function (params) {
console.log('init Called');
this.eGui = document.createElement('span');
};
MyCellRendererSimple.prototype.getGui = function () {
var self = this;
$timeout(function() {
var compiled = $compile('<nice-checkbox checkbox-id="checkbox-2" ng-model="checkboxModal1"></nice-checkbox>')($scope);
$scope.$digest();
self.eGui.appendChild(compiled[0]);
});
return self.eGui;
};

explicit wait in protractor is not working

I am using browser.wait to handle spinner on login page but it actually waiting for the whole time which i have passed as a third parameter.
It should move on to next test case when home page appears after 15min as i have provided the 20mins wait. could anyone please help here.
it('test case', function () {
loginPage.login(browser.params.Login.username, browser.params.Login.password);
browser.wait(function() {
loginPage.Spinner().then(function(presenceOfElement) {
logger.info('App is waiting for spinner to complete'+ presenceOfElement);
return !presenceOfElement
}, 20*60*1000);
});
});
I would suggest rewriting the page object and the test to make it more clear what is going on in the test. Try this:
// loginPage page object
this.getSpinner = function () {
return element(by.tagName('a'));
};
// test
browser.wait(function () {
return loginPage.getSpinner().isPresent().then(function (isSpinnerPresent) {
return !isSpinnerPresent;
)};
}, 20*60*1000);

How to pass a variable to javascript in nested function

I have several protractor / angularjs it blocks that repeat the same bit of code that I would like to put inside a function. I want to just call the function instead of repeating this over and over.
it('should move directly to Draft', function() {
posting_sum_page.locate_action_button.click();
posting_action_page.move_action.filter(function(elem) {
return elem.getText().then(function(text) {
return text === 'Draft';
});
}).click();
});
This part of the block is the repeated part I want to create a function for. I am new to javascript so this is eluding me on how to do this.
return elem.getText().then(function(text) {
return text === 'Draft';
});
}).click();
I need to be able to substitute 'Draft' with different variables. I am using page objects for part of this and I am not sure A) how to create a function like this and pass in my text & B) if it should go on the spec side or the page side? This is probably pretty basic for most folks. But since I am new to javascript I am having trouble wrapping my head around this.
I would extract the whole filter function into a "helpers" module.
helpers.js:
var Helpers = function () {
this.filterByText = function (text) {
return function (elem) {
return elem.getText().then(function(actualText) {
return actualText === text;
});
};
}
}
module.exports = new Helpers();
Usage in the test:
var helpers = require("helpers");
describe("My Test", function () {
it('should move directly to Draft', function() {
posting_sum_page.locate_action_button.click();
posting_action_page.move_action.filter(helpers.filterByText('Draft')).click();
});
});
Maybe something like this?
describe('...something...', function()
{
var clickBtn;
beforeEach(function()
{
clickBtn = function(testText)
{
return posting_action_page.move_action.filter(function(elem)
{
return elem.getText().then(function(currentText)
{
return currentText === testText;
});
}).click();
};
});
it('should move directly to Draft', function()
{
posting_sum_page.locate_action_button.click();
expect(clickBtn('Draft')).toEqual('...something...');
});
});
If you want to reuse the return block only
it('should move directly to' + targetText, function() {
posting_sum_page.locate_action_button.click();
posting_action_page.move_action.filter(function(elem) {
checkSameText(elem, targetText);
}).click();
});
function checkSameText(el, targetText) {
return el.getText().then(function(text) {
return text === targetText;
});
}
I'm unsure what the page object type is for posting_action_page.move_action but what I think you are looking for is using by.buttonText or by.linkText.
// html: <button>Draft</button>
element(by.buttonText('Draft')).click();
// html: <a href="">Draft</button>
element(by.linkText('Draft')).click();
There are other locators that might be helpful like by.partialButtonText and by.partialLinkText.

Is it possible to test Polymer Components outside of a browser?

WCT is great for testing your custom web components, but it requires spinning up a browser to execute the tests.
I am looking for a way to test my components outside of a browser. I looked into jsdom, but it does not currently support Polymer. Any other suggestions?
In case anyone else is following this question, I have made some progress with jsdom.
The trick thus far has been in the created() method:
created: function (error, window) {
window.document.createRange = function () { }
window.getSelection = function () { }
window.Range = function () { }
window.Selection = function () { }
window.CanvasRenderingContext2D = function () { } // Object.getPrototypeOf(require("canvas")(0,0).getContext("2d")) might be better
window.SVGUseElement = window.HTMLUnknownElement
},

How to increase the mocha timeout per suite in a typescript test

I am trying to increase the timeout for mocha tests as they are web requests that form part of an automated UI test suite and therefore can take longer than the default 2000ms.
The code itself works great if I call mocha with the --timeout set to 5000ms or so but the default 2000ms is not enough.
I want to be able to set the timeout per test suite so that the timeout becomes part of the success criteria which might be different on a case by case basis.
before(()=>{
var sw = require('selenium-webdriver');
this.driver = new sw.Builder().withCapabilities(sw.Capabilities.chrome()).build();
var c = require('chai');
c.use(require('chai-webdriver')(this.driver));
this.expect = c.expect;
return this.driver.getWindowHandle();
})
after(() => {
return this.driver.quit();
})
describe('Looking at github', () => {
beforeEach(() => {
this.driver.get('http://stackoverflow.com/');
})
describe('When we take a look at the stack overflow home page', () => {
return it('It does not have crazy cat text in it!', () => {
return this.expect('#h-top-questions').dom.to.not.contain.text("Just cats here!");
});
});
})
Use function intead of an arrow and then just call this.timeout(5000); e.g.
describe('When we take a look at the stack overflow home page', () => {
return it('It does not have crazy cat text in it!', function() {
this.timeout(5000);
return this.expect('#h-top-questions').dom.to.not.contain.text("Just cats here!");
});
});
This is because ()=> captures the surrounding this. More http://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html
An alternative to basarat's answer, along similar lines that uses different syntax (that is effectively confusing in a different way!):
describe('When we take a look at the stack overflow home page', () => {
it('does not have crazy cat text in it!', () => {
expect('#h-top-questions').dom.to.not.contain.text("Just cats here!");
}).timeout(5000);
});

Resources