protractor javascript execution context stack order - javascript

I'm trying to understand the order in which protractor executes according to the execution stack. What is the order in the execution stack after the global execution context (ec) is created and pushed? Is it?
stack
------
|spec1 ec|
|spec2 ec|
|spec3 ec|
|onPrepare ec|
|conf.js ec|
|global ec|
----------
I'm really sure this is not correct because i'm just guessing here. Can someone shed some light on what execution context gets create and when? Thanks.

I can Guide as per my knowledge as below:
Protractor calls conf.js as we write protractor conf.js
So the starting point is conf.js
conf.js generally contains onPrepare where you can keep environment details and reports generation options either customized or you use and package from npm packages.
Also onPrepare has been one of the most useful parts of the config.js file as it allows to define my variables in one place and have access to them across the different spec.js files.
See example
Globals: It is possible to set globals from the Protractor config file with the help of params property:
exports.config = {
// ...
params: {
glob: 'test'
}
// ...
};
You Can use it in Spec as:
browser.executeScript(function (glob) {
// use passed variables on the page
console.log(glob);
}, browser.params.glob);
Sample taken from here
conf.js, onPrepare, globals are part of setup and pre-requistes to run test cases which are in specs some being optional.
After successful creation of those, specs are run which ever way you define it in conf.js running it in parallel/sequentially upon different browsers.
Example:
multiCapabilities: [
{
shardTestFiles: true,
maxInstances: 1,
sequential: true,
browserName: 'chrome',
specs: ['specs/spec1.js','specs/spec2.js','specs/spec3.js']
},
{
shardTestFiles: true,
maxInstances: 1,
sequential: true,
browserName: 'chrome',
specs: ['specs/spec4.js',
'specs/spec5.js',
'specs/spec6.js',
]
}
You can also define suites such as regression, sanity etc and run them individually.
protractor config.js --suite regression,sanity
For your question:
1) conf.js
2) globals & on Prepare
3)specs
I hope you are clear now.

Related

angularjs protractor 3.3.0 not reporting specs

I don't see expected output for a passed run, the assertions are not listed. I expect to see the assertion in this line "1 spec, 0 failures".
The output:
[18:28:06] I/hosted - Using the selenium server at http://localhost:4444/wd/hub
[18:28:06] I/launcher - Running 1 instances of WebDriver
Started
.
1 spec, 0 failures
Finished in 0.854 seconds
[18:28:08] I/launcher - 0 instance(s) of WebDriver still running
[18:28:08] I/launcher - chrome #01 passed
Expected end of run output as seen on protractor's web site, http://www.protractortest.org/#/ "Run the test"):
1 test, 3 assertions, 0 failures
The spec:
describe('Viewing index.html', function() {
'use strict';
beforeEach(function(){
browser.get('/');
});
it('should have pages in left nav', function() {
expect(element.all(by.repeater('page in adminClient.selectedSite.pages')).count()).toBeGreaterThan(0);
});
});
I verified that the by.repeater locator worked:
element.all(by.repeater('page in adminClient.selectedSite.pages')).count()
.then(function(count){
console.log('page count: ' + count);
});
[UPDATE] According to this SO, it is a version issue and there is a recommendation to inject jasmine reporters on the onPrepare hook but that created more runtime errors for me.
stack overflow question
My protractor config:
exports.config = {
allScriptsTimeout: 11000,
chromeOnly: true,
chromeDriver: 'node_modules/protractor/bin/selenium/chromedriver_2.21',
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['tests/e2e/*-spec.js'],
capabilities: {
'browserName': 'chrome'
},
baseUrl: 'http://localhost:8889/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000
}
};
To see the spec names and assertions you must pass the --verbose flag to protractor. If you are using grunt or something to run protractor, you'll need to specify this flag in your config.
EDIT
After reading your edit I believe I have found the solution to your issue. I've tried it with a project of my own and it appears to work.
The underlying problem is that you are likely using protractor 3, which no longer supports many of the previous options particularly within jasmineNodeOpts. To correct this issue, you should downgrade your version of protractor to 2, the latest version is 2.5.1
Here's the related issue on protractor's github repository. It also mentions a custom reporter within the onPrepare hook like you were talking about, but a different one: jasmine-spec-reporter. I got that working as well with a slightly different configuration than what you are using but it does not display the assertions, just has a much better output for the tests, which I quite like:
jasmineNodeOpts: {
print: function () {} // remove dots for each test
},
onPrepare: function () {
var SpecReporter = require('jasmine-spec-reporter');
jasmine.getEnv().addReporter(new SpecReporter({displayStackTrace: true}));
}

Jasmine Runs Test Three Times

I am running Karma/Jasmine/Angular 2.0 tests on my development box. Just recently, Jasmine on my development box decided to start running my tests three times. Yes, exactly three times, every time.
On the first run, everything passes as expected. However, on the second and third pass, all of the same things fail. It always acknowledges that there are 7 tests, but runs 21, and 10 fails (first-grade math out the window)????
This also fails on Travis with SauceLabs. (Note: That links to an older build with 3 tests, but ran 9, and 5 fail???)
I have a screenshot, karma.conf.js file, and one suite which started this whole thing. Any help with be greatly appreciated.
Culprit [TypeScript] (Remove this and problem solved on my dev box):
Full source
describe('From the Conductor Service', () => {
let arr: Array<ComponentStatusModel> = null;
let svc: ConductorService = null;
beforeEach(() => {
arr = [/* Inits the array*/];
svc = new ConductorService();
});
describe('when it is handed a container to hold objects which need to be loaded', () => {
// More passing tests...
/// vvvvv The culprit !!!!!
describe('then when you need to access the container', () => {
beforeEach(() => {
svc.loadedContainer = arr;
});
it('it should always be available', () => {
assertIsLocalDataInTheService(arr, svc.loadedContainer);
});
});
/// ^^^^^ End of culprit !!!!!
});
// More passing tests...
});
Failing Tests:
Browser Screenshots:
Not sure if this is related, but before all of the errors happen, the Jasmine call stack is smaller (left, observe scrollbar). After the errors start, the stack just gets bigger with repeating calls to the same functions (right, observe scrollbar).
Suite Stack is Wrong:
In my test, the Nanobar and Conductor spec files are totally separate. However, you can see the suites array includes stuff from the Nanobar and Conductor specs. Somehow Jasmine mashed these two spec files together (after everything started failing), and resulted in my describe() statements not making any sense when published to the console.
Simplified karma.conf.js:
Full source
module.exports = function (config) {
config.set({
autoWatch: false,
basePath: '.',
browsers: ['Chrome'],
colors: true,
frameworks: ['jasmine'],
logLevel: config.LOG_INFO,
port: 9876,
reporters: ['coverage', 'progress'],
singleRun: true,
coverageReporter: {
// Code coverage config
},
files: [
// Loads everything I need to work
],
plugins: [
'karma-chrome-launcher',
'karma-coverage',
'karma-jasmine'
],
preprocessors: {
'app/**/*.js': ['coverage']
},
proxies: {
// Adjust the paths
}
})
}
Can you try refreshing your browser in your first assertion in each of your test files?
Try this:
browser.restart();
I had the same problem and this fixed it for me.
The first thing is these test run randomly. If you pass some data in any test case if you think you can resue that it is not possible.
You have to declare the data in before each so all test cases get data.
All test cases run independently.
If you are using array or object you must have to use this after deep cloning because array and object works on the reference. If you manipulate any value it will also change the original array.
In most of the cases if the test fails there may be an error of data you are passing in test cases.
I would try to debug this and pinpoint the exact cause.
Usually happens when I have redirection code or any reload code inside the functions I'm testing.
You can try adding an f to the prefix of describe and it (i.e. fdescribe and fit)

How do I Run multiple protractor test suites at once?

First attempt at using Protractor. I would like to be able to run multiple suites in succession.
I have an application that is one big angular form with different scenarios.
I have expected results for each scenario and would like to enter one command and run through each test.
I thought I could just use comma separated like:
protractor config.js --suite=rf1_breast, rf1_ovarian, rf1_pancreatic
But I am getting the error:
Error: more than one config file specified
Which is strange as there is only the one config file which is in the directory where I am running protractor.
Here is my config.js:
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
capabilities: { 'browserName': 'chrome' },
framework: 'jasmine2',
suites: {
rf1_breast: './rf1-ashkenazi-hboc/Breast/specs/*_spec.js',
rf1_ovarian: './rf1-ashkenazi-hboc/Ovarian/specs/*_spec.js',
rf1_bladder_fail: './rf1-ashkenazi-hboc/Bladder-expected-fail/specs/*_spec.js',
rf1_pancreatic: './rf1-ashkenazi-hboc/Pancreatic/specs/*_spec.js',
rf1_prostate: './rf1-ashkenazi-hboc/Prostate/specs/*_spec.js'
},
onPrepare: function() {
/* global angular: false, browser: false, jasmine: false */
browser.manage().window().setSize(1600, 1600);
// Disable animations so e2e tests run more quickly
var disableNgAnimate = function() {
angular.module('disableNgAnimate', []).run(['$animate', function($animate) {
$animate.enabled(false);
}]);
};
browser.addMockModule('disableNgAnimate', disableNgAnimate);
},
jasmineNodeOpts: { showColors: true }
};
Is there a better way around getting each scenario run?
Don't put spaces after commas:
protractor config.js --suite rf1_breast,rf1_ovarian,rf1_pancreatic
In your config.js
If you want to run the script as a suite comment out the spec line
// specs: ['src/com/sam/scriptjs/alertexamplespec.js']
give the suite name and location
suites: {
//Suite name and location give * to run all the specs or provide the name
smoke: ['./smoke/*.spec.js'],
endtoend: ['src/com/sam/scriptjs/*.spec.js'],
//Futhermore you can select few test specs
testfew: ['./smoke/editorder.spec.js','./smoke/cancelorder.spec.js']
},
then in cmd type protractor filenameconfig.js
Try to make your suite composed by multiple files. I Have a line for the test I currently work on and another with the entire suite of tests:
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/**/1.Landing.Page.ts',
'./e2e/**/2.Confirmation.Page.ts',
'./e2e/**/3.PersonalData.Page.ts',
'./e2e/**/4.sms.Page.ts',
'./e2e/**/5.idCard.Page.ts'
],
}
This works for me.

Getting [ng:test] no injector found for element argument to getTestability error when swithching between different single page applications

I am running tests on protractor. The website that I am testing bootstrapping angularjs manually. While running tests this is the error that I get even though steps keep on executing
Error while waiting for Protractor to sync with the page:
"[ng:test] no injector found for element argument to getTestability
\nhttp://errors.angularjs.org/1.3.15/ng/test"
On going to the link
https://docs.angularjs.org/error/ng/test
The explanation that I am getting is this
Angular's testability helper, getTestability, requires a root
element to be passed in. This helps differentiate between different
Angular apps on the same page.
This error is thrown when no injector is found for root element.
It is often because the root element is outside of the ng-app.
I get this error when I switch from one SPA to another. The website that I am testing doesn't use ng-app anywhere.
As far as I have understand that rootelement for ng-app is usually html or body
If I use body in my conf.js. I am able to run other tests succesfully but when I navigate from one SPA to another then the tests sometime gives the above error
This is my conf.js file
var customReport = require('./Utilities/HtmlWriter.js').htmlWriter;
//config dependencies - all the js files in tests folder ending with -spec.js will be executed
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub', //Selenium webdriver instance needed to run the tsts
specs: ['./tests/functional/EditAppInfo_spec.js'], // All tests need to be placed inside tests folder and should end with _spec.js
baseUrl:'http://url.in.test.net',
capabilities: {
'browserName': 'firefox',
},
/*
multiCapabilities:[
{
'browserName': 'chrome'
},
{
'browserName': 'firefox'
},
{
'browserName': 'internet explorer',
}
],
*/
getPageTimeout:30000,
allScriptsTimeout:30000,
rootElement: "body",
jasmineNodeOpts: {
onComplete: null,
isVerbose: true,
showColors: true,
includeStackTrace: true,
defaultTimeoutInterval: 10000000000000
},
onPrepare: function() {
}
};
Do I need to change the root element as I navigate in between different SPA's using in between spec files
browser.rootElement
Can anyone help me out on this. If I get the dev to put an ID on top of the div where the SPA is being loaded will that solve?
I ran into the same issue now. Earlier I was testing an app whose body/div class was in the conf.js like this
rootElement: '.classOfDivUnderBodyOfAnSPA',
Now I am testing another app and I hot this and I commented this out and added
rootElement: '.classOfDivUnderBodyOfNewSPA',
this fixed the issue.
Note: I am not saying which element to look at (like body that you have). I have the class value of the div under body. Hope this helps!
Revision: I added both the div together, comma seperated and that helped too. So no need to live with one or other.
rootElement: '.class1, .class2',
I just fixed this error by changing the
`framework: jasmine`
property in my protractor.conf.js to
`framework: jasmine2`

Output tests to browser with Karma

I am using Karma to test my project and can see tests passing an failing in the console window, however, how do I get these to show in the browser? The browser only has a green bar (even though a test is failing) with
Karma v0.10.2 - connected
Written in it.
I have tried addong singleRun :false to the karma.config.js file.
The config file looks like this:
module.exports = function (config) {
config.set({
basePath: '../',
files: [
'app/lib/angular/angular.js',
'app/lib/angular/angular-*.js',
'test/lib/angular/angular-mocks.js',
'app/js/**/*.js',
'test/unit/**/*.js'
],
autoWatch: true,
singleRun: false,
frameworks: ['jasmine'],
browsers: ['Chrome'],
plugins: [
'karma-junit-reporter',
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-jasmine'
],
junitReporter: {
outputFile: 'test_out/unit.xml',
suite: 'unit'
}
})
}
matthias-schuetz wrote a plugin that claims to produce html test output.
https://npmjs.org/package/karma-htmlfile-reporter
Along with the instructions on the plugin page I had to include a reference to the plugin in the Karma config -
plugins: [
'karma-htmlfile-reporter'
]
Accroding to Documention, even not very perfect:
If 'singleRun' is false, it will set the ci-mode on, so, make it true, and you will see some failed red status on the top bars of browers.
There is no straight forward way to do this with Karma.
The "best" way to solve this problem would be to hunker down and write a html-reporter for karma (which would make a lot of us other Karma users very happy).
If this is too much work for you, the second best thing is to use the junit reporter which generates an xml file. You can then post-process the xml file in some way that turns it into a HTML-file which you can then view in your browser
I wanted to display HTML5 Web Notifications with Karma so I wrote something quick to get it to work with Karma version 0.11. Might behave slightly different with other versions. I load this script in with the rest of my application scripts, it will store the karma test results and after completion it will determine the success of the test and then reset to the original karma functions so they're not changed when this script gets run again.
// store all my test results
var results = [];
// Wrap the karma result function
var resultFunc = window.__karma__.result;
window.__karma__.result = function(result){
// run the original function
resultFunc(result);
// push each result on my storage array
results.push(result);
}
// wrap the karma complete function
var completeFunc = window.__karma__.complete;
window.__karma__.complete = function(result){
// run the original function
completeFunc(result);
// determine success
var success = results.every(function(r){ return r.success });
if (success) {
// display a success notification
}
else {
// display a test failure notification
}
// reset the result function
window.__karma__.result = resultFunc;
// reset the complete function
window.__karma__.complete = completeFunc;
}

Categories