Below is my config file that I use to run a single user and multiple test suite.Now, am having a issue where I want to run few protractor suites with User A and few protractor test suite with User B. I don't know how to achieve this in protractor.
exports.config = {
capabilities: {
browserName: 'chrome'
},
suites: {
loginAndNavigate: 'e2e/specFiles/LoginAndNavigateSpec.js',
homepage: 'e2e/specFiles/policiesList_HomepageSpec.js',
versionPage: 'e2e/specFiles/ER_VersionsPageSpec.js'
policyDetails: 'e2e/specFiles/policyDetailsPageSpec.js'
},
seleniumServerJar: '../node_modules/protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-2.53.1.jar',
chromeDriver: '../node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.26',
baseUrl: 'https://shared.qa.com/EdgeAuth/logindirect.jsp',
params: {
login: {
user: ‘user ',
password: 'abc123'
}
},
onPrepare: function() {
global.EC = protractor.ExpectedConditions;
browser.getCapabilities().then(function(c) {
console.log(c.get('browserName'));
});
global.Utils = require('./e2e/utils.js');
require('./e2e/matchers.js');
require('./e2e/customLocators.js');
},
framework: 'jasmine2',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 100000
}
};
You can provide new param (user details) and suite details when you run the test.
For the params object use --params.login.user "User B" etc etc to overwrite config file details.
For the suites you can use --suite=loginAndNavigate or if more than one then --suite=loginAndNavigate,homepage to choose what to run.
You will need the proper combination of these two to suit your needs.
https://github.com/angular/protractor/blob/master/lib/config.ts
Related
Is there any way to debug Webdriverio tests using nodeJS and WebStorm?
I've found some conclusion here and this is actually my problem: Run WebdriverIO tests via Mocha in WebStorm
But this solution doesn't fit to my problem now;
I've set up Babel to compile my BDD tests
I've set tests.config.js
module.exports = { maxInstances: 1,
capabilities: [{ browserName: 'chrome' }],
execArgv: ['--inspect'] : [],
specs: ['**/some/spec.js']
mochaOpts: {
ui: 'bdd',
compilers: ['js:#babel/register'],
timeout: 150000
} }
and babel.conf.js
module.exports = {
presets: [
['#babel/preset-env', {
targets: {
node: 12
}
}]
]
}
then I've created nodeJS configuration like it said here at answer: Run WebdriverIO tests via Mocha in WebStorm
Set breakpoint at test
describe("test", function(){
it ("this is a BDD test",
function(){
breakpoint here>> do_some_action();
})
})
But when I try to launch my tests in debug mode nothing happens and I see "connnected to localhost:port" message. and I can't go to breakpoint; there are no errors;
there was problem with a wdio.conf.js file. If you don't set specs file >> there aren't no errors. But launching is incorrect. I've set config like this:
module.exports =
{
capabilities: [{
maxInstances: 6,
browserName: 'chrome',
baseUrl: "some-url/",
browserVersion: '67.0'}]
specs: [
'./this/is/spec.js']
mochaOpts: {
ui: 'bdd',
require: ['#babel/register'],
timeout: 150000
},
And debug works after this. It's not too har as I though :) If there are some questions - > I'm glad o answer
I have one file of config which runs tests in one browser using capabilities.
Now I have created one more separate config file which contains multiCapabilites and will run same tests in multiple browsers.
I want to optimize configs so I second config file I write multiCapabilities for first config and used
delete firstConfig['capabilities'];
to ignore the capabilities from first config and use all other params from firstConfig and use multiCapabilities from 2nd config and run.
Expected result:
params in configs should not be duplicated in both configs, only multiCapabilities is the change, rest of config is same.
Use a base configuration file
Having a base configuration file and another file that extends from it might be a better approach. For this example, we will look at my base configuration file:
var env = require('./environment');
// This is the configuration for a smoke test for an Angular TypeScript application.
exports.config = {
seleniumAddress: env.seleniumAddress,
framework: 'jasmine',
specs: [
'ng2/async_spec.js'
],
capabilities: env.capabilities,
baseUrl: env.baseUrl,
allScriptsTimeout: 120000,
getPageTimeout: 120000,
jasmineNodeOpts: {
defaultTimeoutInterval: 120000
}
};
Create a second config from the base config
From there, we did something similar to your question where we removed the capabilities and added multicapabilities. (https://github.com/angular/protractor/blob/master/spec/ciNg2Conf.js). In addition, since we were running on Sauce Labs, we also decided to increase our timeouts.
exports.config = require('./angular2Conf.js').config;
exports.config.sauceUser = process.env.SAUCE_USERNAME;
exports.config.sauceKey = process.env.SAUCE_ACCESS_KEY;
exports.config.seleniumAddress = undefined;
// TODO: add in firefox when issue #2784 is fixed
exports.config.multiCapabilities = [{
'browserName': 'chrome',
'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
'build': process.env.TRAVIS_BUILD_NUMBER,
'name': 'Protractor suite tests',
'version': '54',
'selenium-version': '2.53.1',
'chromedriver-version': '2.26',
'platform': 'OS X 10.11'
}];
exports.config.capabilities = undefined;
exports.config.allScriptsTimeout = 120000;
exports.config.getPageTimeout = 120000;
exports.config.jasmineNodeOpts.defaultTimeoutInterval = 120000;
I hope that helps.
Update:
Per comments below, setting the config.capabilities to undefined did not work; however, setting config.capabilities to false did work.
Prepare a capabilities provider to define vary capabilities, and exports a function to return a capabilities array according to the cmd line params.
// capabilities.provider.js
var capabilities = {
chrome: {
browserName: 'chrome'
},
chrome-headless {
browserName: 'chrome',
},
firefox: {
browsername: 'firefox'
},
...
};
exports.evaluate=function(){
var caps = 'chrome';
process.argv.slice(3).forEach(function(kvp){
if(kvp.includes('--caps=')) {
caps = kvp.split('=')[1] || caps;
}
})
var _caps = [];
caps.split(',').forEach(function(cap){
if(Object.keys(capabilities).includes(cap)) {
_caps.push(capabilities[cap])
}
})
return _caps;
};
protractor config.js
var capsProvider = require('./capabilities.provider');
exports.config = {
seleniumAddress: '',
framework: 'jasmine',
specs: [
'ng2/async_spec.js'
],
params: {
},
multiCapabilities: capsProvider.evaluate(),
baseUrl: env.baseUrl,
allScriptsTimeout: 120000,
getPageTimeout: 120000,
jasmineNodeOpts: {
defaultTimeoutInterval: 120000
}
};
Specify caps from cmd line:
protractor config.js --caps=chrome,firefox,ie,safari
I have a setup of my angular-app and a separate selenium server as docker-compose setup
my protractor setting looks like this
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: false,
baseUrl: 'http://user-frontend:4200/',
seleniumAddress: 'http://selenium:4444/wd/hub',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
now I run the command to run the end2end tests using protractor:
ng e2e --no-serve
All my tests are failing, and when I debug the selenium server and take screenshots, I see it is trying to connect to itself (localhost) instead of back to the application host baseUrl: 'http://user-frontend:4200/',
any Idea what I am doing wrong here?
Are you sure that browser.baseUrl (or browser.get()) is not set elsewhere?
Here's the library:
//library.js
var exports = module.exports = {};
exports.login = function(user_login, user_password) {
var input;
input = element(by.model('loginInfo.login'));
input.sendKeys(user_login);
expect(input.getAttribute('value')).toBe(user_login);
input = element(by.model('loginInfo.password'));
input.sendKeys(user_password);
expect(input.getAttribute('value')).toBe(user_password);
browser.sleep(1000);
browser.driver.actions().sendKeys(protractor.Key.ENTER).perform();
browser.sleep(1000);
};
And this is my config file:
//config.js
var lib = require("./library.js");
exports.config = {
directConnect: true,
onPrepare: function() {
browser.driver.manage().window().maximize();
},
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['messages.js'],
// Options to be passed to Jasmine.
jasmineNodeOpts: {
defaultTimeoutInterval: 50000
}
};
And here's how I'm calling the login fn in the messages.js file:
lib.login('xxx', 'yyyyy');
However, this last line above is giving me an error: 'lib is not defined'
It looks like you are trying to run a protractor test from your library.js file.
Instead of doing that, following the guidelines that http://www.protractortest.org/#/ instructs. That is, the config.js file is for configuring the environment and the spec.js file is for testing. As such, try this instead:
/*
* library-spec.js
*/
var input;
describe('Login Test', function() {
it('should enter login information and send the Enter key to login', function() {
input = element(by.model('loginInfo.login'));
input.sendKeys(user_login);
expect(input.getAttribute('value')).toBe(user_login);
input = element(by.model('loginInfo.password'));
input.sendKeys(user_password);
expect(input.getAttribute('value')).toBe(user_password);
browser.sleep(1000);
browser.driver.actions().sendKeys(protractor.Key.ENTER).perform();
browser.sleep(1000);
});
});
And the config file will look like:
//config.js
exports.config = {
directConnect: true,
onPrepare: function() {
browser.driver.manage().window().maximize();
},
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['library-spec.js'],
// Options to be passed to Jasmine.
jasmineNodeOpts: {
defaultTimeoutInterval: 50000
}
};
However, if you need that library.js file to be run before each or before all your tests, put it into your messages.js file.
From your messages.js file, within your describe block you would add:
beforeEach(function() {
lib(username, password); //where username and password are string vars
});
or
beforeAll(function() {
lib(username, password); //where username and password are string vars
});
And, as a final note, if you leave your library.js file as is, here is some cleanup:
//library.js
module.exports = login;
function login(user_login, user_password) {
var input;
input = element(by.model('loginInfo.login'));
input.sendKeys(user_login);
expect(input.getAttribute('value')).toBe(user_login);
input = element(by.model('loginInfo.password'));
input.sendKeys(user_password);
expect(input.getAttribute('value')).toBe(user_password);
browser.sleep(1000);
browser.driver.actions().sendKeys(protractor.Key.ENTER).perform();
browser.sleep(1000);
};
Note how the module.exports line replaces the line that you had. Also I've changed the exports.login to function login. Then you would...
var login = require('./login');
login('user', 'pass');
where it will be needed.
I am using the code bellow for arguments which are using in protractor configuration file
protractor: {
options: {
keepAlive: true,
configFile: "test/config.js",
args:{
params:{
user:"user1",
password:"password1"
}
}
},
and retrieving in protractor conf file as browser.params.user,browser.params.password
These are working files.
I want to change the user and password values from command.
How to change the values?
This is a simple work around:
When you pass a parameter to your grunt task:
grunt e2e --user=alex --password=password
it's available as
grunt.option('user')
You can then edit the values you have in the config using:
var protConfig = grunt.config.get('protractor');
protConfig.options['someKey']=newValue;
grunt.config('protractor', protConfig);
grunt.task.run('protractor');
Not sure this is the best way to go about it, but it's working fine for me.
Also notice that we're wrapping the protractor task rather than calling it right away
how to fetch --user argument in protractor Specs?
In the code below I register a task "myprotractor" and whatever comes after the task as argument will go as parameter into the anonymous function:
grunt myprotractor:dev:pwd
module.exports = function(grunt) {
grunt.registerTask('myprotractor', function(user, pwd) {
console.log(user + pwd);
grunt.config('protractor', {
options: {
keepAlive: true,
configFile: "test/config.js",
args: {
params: {
user: user,
password: pwd
}
}
}
});
//here I am running the task
grunt.task.run([
'protractor'
]);
});
};
If you need you can configure 2 targets for protractor, having some common configuration and the args being set depending if you wish them from cmd or from config.
grunt myprotractor:cmd:dev:pwd
module.exports = function(grunt) {
grunt.registerTask('myprotractor', function(target, user, pwd) {
console.log(user + pwd);
grunt.config('protractor', {
options: {
keepAlive: true,
configFile: "test/config.js"
},
cmd: {
options: {
args: {
params: {
user: user,
password: pwd
}
}
}
},
config: {}
});
//here I am running the task with a target
grunt.task.run([
'protractor:' + target
]);
});
};