Set static path for karma runner - sapui5

I was able prepare my OpenUI5 app for testing. I am having issue with the working directory for tests, because for my test I need to use a pre-populated sqlite3 database. For testing I use chrome with parameters --user-data-dir="C:\tmp" --profile-directory="karma", and I can place this file into chrome profile path. But I am not able to do this with karma, because karma always start with randomly generated id in path (karma-xxxxxx).
I am trying run custom browser config, with above chrome parameters, but it does not work.
module.exports = function(config) {
"use strict";
var chromeFlags = [
"--window-size=1280,1024",
"--disable-web-security",
"--allow-file-access-from-files",
'--user-data-dir="C:\\tmp"',
'--profile-directory="karma"'
];
config.set({
basePath: '',
ui5: {
type: "application",
preload: 'async',
animation: 'false',
paths: {
webapp: "www", // application
}
},
frameworks: ["ui5"],
browsers: ["CustomChrome"],
browserConsoleLogOptions: {
level: "error"
},
customLaunchers: {
CustomChrome: {
base: "Chrome",
flags: chromeFlags
},
CustomChromeHeadless: {
base: "ChromeHeadless",
flags: chromeFlags
}
},
});
};
with this config, chrome always start like this, so automatic testing does not work:

Related

Protractor to dynamically choose browser based on input

I am new to protractor and I want to be able to run my chrome browser painted or headless.
So I set up something like this
let chrome = {
browserName: 'chrome',
platform: 'MAC',
'max-duration': '1800',
};
let chromeHeadless = {
browserName: 'chrome',
chromeOptions: {
args: [ "--headless", "--disable-gpu", "--window-size=800,600" ]
}
};
browserDefault = browser.params.browserToUse
exports.config = {
params: {
'browserToUse': "get from user'
},
capabilities: browserDefault,
}
and i ran this code as
protractor config.js --params.browserToUse='chromeHeadless'
But this does not work. Protractor fails saying it does not understand "browser.params.browserInput". Whats the right way to make protractor dynamically choose chrome or chromeheadless based on the input
The global variable browser is only init when code run into onPrepare(). You used browser outside onPrepare() function, browser have not been inited, it is undefined, so you met the error.
Another point you need to get it's when the variable browser inited, a browser window has been opened, means protractor has know which capabilities to launch the browser. Therefore you can't use browser.params.xxx to specify which capabilities, you need to tell protractor the capabilities before it init the browser variable.
let capabilitiesMap = {
'chrome-headful' : {
browserName: 'chrome',
platform: 'MAC',
'max-duration': '1800',
},
'chrome-headless': {
browserName: 'chrome',
chromeOptions: {
args: [ "--headless", "--disable-gpu", "--window-size=800,600" ]
}
}
};
let browserToUse = 'chrome-headful'; // set default value
// extract the browserToUse value from cli
process.argv.slice(3).forEach(function(arg) {
var name = arg.split('=')[0];
var value = arg.split('=')[1];
var name = name.replace('--', '');
if (name === 'browserToUse') {
if (Object.prototype.hasOwnProperty.call(capabilitiesMap, value) ) {
browserToUse = value;
}
}
});
let config = {
seleniumAddress: '',
specs: [],
onPrepare: function() {}
};
config.capabilities = capabilitiesMap[browserToUse];
exports.config = config;
CLI example: protractor conf.js --browserToUse=chrome-headless
I also came across this issue and soleved it using the getMultiCapabilities() function in your conf.js
const _ = require('lodash');
let capabilities = {
chrome: {
browserName: 'chrome',
platform: 'MAC',
'max-duration': '1800',
},
chromeHeadless : {
browserName: 'chrome',
chromeOptions: {
args: [ "--headless", "--disable-gpu", "--window-size=800,600" ]
}
}
}
getMultiCapabilities() {
const browsers = this.params.browserToUse.split(',');//if you pass more than one browser e.g chrome,chromeHeadless
const cap = _(capabilities).pick(browsers).values().value(); //this uses the lodash npm module
return cap;
},
In a testing context working with just Chrome, I did the following. In capabilities:
chromeOptions: {
args: []
}
beforeLaunch: function() {
//at this point browser is not yet defined, so process command line directly
if (process.argv[process.argv.length-1].search('headless=true')>-1){
config.capabilities.chromeOptions.args.push("--headless");
config.capabilities.chromeOptions.args.push("--disable-gpu");
config.capabilities.chromeOptions.args.push("--window-size=1600,1000");
}
}
That way by the time the browser was launched, it had the right configuration. Where I have "headless=true", you might want "Chrome-headless."
And then on the command line I call it like you do with --params.headless=falseso that should I want to find it in the script itself later (after the browser has launched), it is readily available.
Note I had just one command line parameter and control of the command line, so it felt okay to assume this parameter was the last.

SystemJS and KarmaJS: TypeError: System.import is not a function

I am trying to get my project working with Karma and SystemJS. I am using the karma-systemjs plugin with karma.
I keep getting the error below about System.import.
I believe it is because SystemJS is not being loaded by the time the karma-systemjs plugin runs. Please tell me what I am doing wrong.
Project structure
SystemJS configuration (system.conf.js)
System.config({
baseUrl: '',
defaultJSExtensions: true,
map: {
'jquery': 'vendor/kendo/js/jquery.min.js',
'angular': 'vendor/kendo/js/angular.js',
'kendo': 'vendor/kendo/js/kendo.all.min.js',
'angular-mocks': 'vendor/bower_components/angular-mocks/angular-mocks.js',
'angular-ui-router': 'vendor/bower_components/angular-ui-router/release/angular-ui-router.min.js',
'angular-toastr': 'vendor/bower_components/angular-toastr/dist/angular-toastr.tpls.min.js',
'angular-local-storage': 'vendor/bower_components/angular-local-storage/dist/angular-local-storage.min.js'
},
paths: {
'systemjs': 'vendor/bower_components/system.js/dist/system.js',
'system-polyfills': 'vendor/bower_components/system.js/dist/system-polyfills.js'
},
meta: {
'vendor/kendo/js/jquery.min.js': {
format: 'global',
exports: '$'
},
'vendor/kendo/js/angular.js': {
format: 'global',
deps: [
'vendor/kendo/js/jquery.min.js'
],
exports: 'angular'
},
'vendor/kendo/js/kendo.all.min.js': {
format: 'global',
deps: [
'vendor/kendo/js/angular.js'
],
exports: 'kendo'
},
'vendor/bower_components/angular-ui-router/release/angular-ui-router.min.js': {
format: 'global',
deps: [
'vendor/kendo/js/angular.js'
]
},
'vendor/bower_components/angular-mocks/angular-mocks.js': {
format: 'global',
deps: [
'vendor/kendo/js/angular.js'
],
exports: 'angular.mock'
},
'vendor/bower_components/angular-toastr/dist/angular-toastr.tpls.min.js': {
format: 'global',
deps: [
'vendor/kendo/js/angular.js'
]
},
'vendor/bower_components/angular-local-storage/dist/angular-local-storage.min': {
format: 'global',
deps: [
'vendor/kendo/js/angular.js'
]
}
}
});
Promise.all([
System.import('kendo'),
System.import('angular-mocks'),
System.import('angular-ui-router'),
System.import('angular-toastr'),
System.import('angular-local-storage')
]).then(function () {
System.import('angular')
.then(function (angular) {
System.import('ng/app/app.module')
.then(function (app) {
angular.bootstrap(document, ['s9.app']);
}, function (err) {
console.log(err);
});
}, function (err) {
console.log(err);
});
});
//# sourceMappingURL=system.conf.js.map
karma.conf.js
// Karma configuration
var configure = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '.',
transpiler: null,
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['systemjs', 'jasmine'],
systemjs: {
// Path to your SystemJS configuration file
configFile: 'system.conf.js',
// Patterns for files that you want Karma to make available, but not loaded until a module
// requests them. eg. Third-party libraries.
serveFiles: [
'vendor/kendo/js/**/*.js',
'vendor/bower_components/**/*.js',
'ng/**/*.js',
'test/**/*Spec.js'
],
config: {
paths: {
'systemjs': 'vendor/bower_components/system.js/dist/system.js',
'system-polyfills': 'vendor/bower_components/system.js/dist/system-polyfills.js'
}
}
},
// list of files / patterns to load in the browser
files: [
{pattern: 'vendor/kendo/js/**/*.js', included: false},
{pattern: 'vendor/bower_components/**/*.js', included: false},
{pattern: 'ng/**/*.js', included: false},
{pattern: 'test/**/*Spec.js', included: false}
],
// list of files to exclude
exclude: [],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_DEBUG,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
});
};
module.exports = configure;
//# sourceMappingURL=karma.conf.js.map
Error
I fixed this by moving the bootstrap code out of the config code. Apparently when using the karma-systemjs plugin System.import is not available yet when this is called (although it is at normal runtime).
What I did: I moved the bootstrap code (i.e. Promise.all([....) into into a separate file called bootstrap.js (name is not important) and then in my index.html I added them in this order:
Also from this link (the karma system js plugin author says): https://github.com/rolaveric/karma-systemjs/issues/71
I see the problem. It's because you've got your bootstrapping code
(eg. System.import() calls) inside your SystemJS config file -
system.conf.js karma-systemjs expects just a simple System.config()
call that it can then intercept to find out where your transpiler and
polyfills are. It does this by evaluating your config file with a fake
System object which simply records whatever is passed to
System.config(). This fake object has no System.import() method, which
causes your error.
I'd recommend moving your bootstrapping code into a separate file (I
personally put it in a script tag with my HTML). Otherwise you'll run
into similar problems if you try to use systemjs-builder, and you
probably don't want angular.bootstrap() to be called at the start of
your unit tests.

Protractor: Paramaterized Configuration

There are several elements of a Protractor configuration that I need to modify at run-time, most importantly some values of the multiCapabilities object:
...
multiCapabilities: [
{
'build': buildNumber,
'app': 'app' + buildNumber + '.apk',
'browserName': '',
'appiumVersion': '1.4.16',
'deviceName': 'Android Emulator',
'deviceOrientation': 'portrait',
'platformVersion': '5.1',
'platformName': 'Android',
'autoWebview': true
},
{
...
}
],
...
Specifically, I'm running these tests against a specific build of an app that has been uploaded to SauceLabs. I'd like to be able to somehow set the 'build' and 'app' values dynamically.
Unfortunately, the Grunt Protractor Runner does not support the multiCapabilities feature, otherwise it could be handled using that wrapper.
One option would be to use browser.params and parameterize your tests from the command-line arguments. In this case, use getMultiCapabilities() method:
getMultiCapabilities: function () {
var buildNumber = browser.params.build,
app = browser.params.app;
return [
{
'build': buildNumber,
'app': app,
'browserName': '',
'appiumVersion': '1.4.16',
'deviceName': 'Android Emulator',
'deviceOrientation': 'portrait',
'platformVersion': '5.1',
'platformName': 'Android',
'autoWebview': true
},
{
...
}
],
},
Usage:
protractor protractor.conf.js --params.build="build" --params.app="app"

Maximize nw.js window from protractor doesn't work

I want to maximise the window from protractor. I am testing a nw.js app.
I added the below line in onPrepare statement in protractor-conf.js, but nothing worked
browser.driver.manage().window().maximize();
setSize also doesn't work
browser.driver.manage().window().setSize(800, 600);
In all the cases I am getting the below error.
var template = new Error(this.message);
^
UnknownError: unknown error: cannot get automation extension
from unknown error: page could not be found: chrome-extension://aapnijgdinlhnhlmodcfapnahmbfebeb/_generated_background_page.html
This is the e2e configuration,
protractor-conf.js
'use strict';
var path = require('path');
var nw = require('nw');
exports.config = {
chromeDriver: './support/chromedriver',
directConnect: true,
specs: ['e2e/**/*.js'],
rootElement: 'html',
capabilities: {
browserName: 'chrome',
chromeOptions: {
binary: nw.findpath()
}
},
onPrepare: function() {
// By default, Protractor use data:text/html,<html></html> as resetUrl, but
// location.replace (see http://git.io/tvdSIQ) from the data: to the file: protocol is not allowed
// (we'll get ‘not allowed local resource’ error), so we replace resetUrl with one
// with the file: protocol (this particular one will open system's root folder)
browser.resetUrl = 'file://';
// This isn't required and used to avoid ‘Cannot extract package’ error showed
// before Protractor have redirected node-webkit to resetUrl.
browser.driver.get('file://' + path.resolve('app/index.html'));
}
};
Is there a way to resolve this ?
I am testing this on Ubuntu.
Did you try to set the arguments for chrome inside capabilities ?
http://peter.sh/experiments/chromium-command-line-switches/
chromeOptions: {
args: [
'--start-maximized',
]
}

How do I parameterize the baseUrl property of the protractor config file

I need to run my protractor tests in different contexts with different baseUrls in the config files. I don't want to use separate config files for each situation since that is more difficult to maintain. Rather, I want to pass the base url in as a command line parameter. Here is what I have tried so far:
The protractor.conf.js:
exports.config = {
onPrepare : {
...
exports.config.baseUrl = browser.params.baseUrl;
...
}
}
And to invoke protractor:
protractor protractor.conf.js --params.baseUrl 'http://some.server.com'
This does not work since it seems like the browser instance is already configured before onPrepare is called.
Similarly, I have tried this:
exports.config = {
baseUrl : browser.params.baseUrl
}
But this doesn't work either since it seems like the browser instance is not available when the config is being generated.
It looks like I can use standard node process.argv to access all command line arguments, but that seems to be going against the spirit of protractor.
What is the best way for me to do what I need to do?
Seems like this is already possible, but the documentation is spotty in this area. Looking at the code, however, protractor does support a number of seemingly undocumented command line arguments.
So, running something like this will work:
protractor --baseUrl='http://some.server.com' my.conf.js
The other option is to use gruntfile.js and have it call the protractor config file.
//gruntfile.js
module.exports = function (grunt) {
grunt.registerTask("default", "", function () {
});
//Configure main project settings
grunt.initConfig({
//Basic settings and infor about our plugins
pkg: grunt.file.readJSON('package.json'),
//Name of plugin
cssmin: {
},
protractor: {
options: {
configFile: "conf.js", // Default config file
keepAlive: true, // If false, the grunt process stops when the test fails.
noColor: false, // If true, protractor will not use colors in its output.
args: {
baseUrl: grunt.option('baseUrl') || 'http://localhost:6034/'
}
},
your_target: { // Grunt requires at least one target to run so you can simply put 'all: {}' here too.
options: {
configFile: "conf.js", // Target-specific config file
args: {
baseUrl: grunt.option('baseUrl') || 'http://localhost:63634/'
}
}
},
},
//uglify
uglify: {
}
});
//Load the plugin
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-protractor-runner');
//Do the Task
grunt.registerTask('default', ['cssmin']);
};
the Protractor config file: conf.js
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
args: ['--no-sandbox']
}
},
chromeOnly: true,
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['specs/*/*_spec.js'],
suites : {
abcIdentity : 'specs/abcIdentity/*_spec.js' //picks up all the _spec.js files
},
params: {
UserName: 'abc#test.com',
Password: '123'
},
// Options to be passed to Jasmine.
jasmineNodeOpts: {
defaultTimeoutInterval: 30000,
includeStackTrace: true
},
onPrepare: function () {
browser.driver.manage().window().maximize();
if (process.env.TEAMCITY_VERSION) {
var jasmineReporters = require('jasmine-reporters');
jasmine.getEnv().addReporter(new jasmineReporters.TeamCityReporter());
}
}
};
//To run with default url http://localhost:6034
grunt protractor
//To run with any other url
grunt protractor --baseUrl:"http://dev.abc.com/"
I know, old one. but if anyone is still looking for a way to define a url based on capability (I had to do this because Ionic 5 will run in browser on port 8100, but in the app - unchangable - without port declaration on port 80, I use Appium)
add a baseUrl parameter inside your capability declaration.
{
browserName: 'chrome',
baseUrl: 'http://localhost:8100' //not required but as example
}
{
...
app: 'path to app.apk',
baseUrl: 'http://localhost'
...
}
and then configure your onPrepare method as follows.
async onPrepare() {
const config = await browser.getProcessedConfig();
if(config.capabilities.hasOwnProperty('baseUrl')) {
browser.baseUrl = config.capabilities.baseUrl;
}
}
OnPrepare runs for each capability you define in your multiCapabilities array. the getProcessedConfig returns the config as you defined it, with the addition of the current capability. Since that method returns a promise, I use async/await for readability.
This way, you can have multiple capabilities running, with each different a different host.
Base url should be declared baseUrl: "", in config.ts
I am using cucumber hooks and the below code is added in hooks file to pass the required url based upon the environments
if(browser.params.baseUrl==="QA"){
console.log("Hello QA")
await browser.get("https://www.google.com");
} else {
console.log("Hi Dev")
await browser.get("https://www.gmail.com");
}
run the tests using protractor command
protractor --params.baseUrl 'QA' typeScript/config/config.js --cucumberOpts.tags="#CucumberScenario"