gulp-protractor error with chrome v54 / web driver v2.25 - google-chrome

Due to the latest update of chrome (v54) we've noticed our protractor tests failing. We attempted to update to the latest version of gulp-protractor (v3.0.0) which in turn downloads the latest web driver (v2.25) to resolve the issue but unfortunately a new error occurs we've been unable to resolve.
Everything worked fine before chrome's update.
Our protractor configuration is as follows:
exports.config = {
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
onPrepare: function () {
var fs = require('fs');
var testDir = 'testresults/';
if (!fs.existsSync(testDir)) {
fs.mkdirSync(testDir);
}
var jasmineReporters = require('jasmine-reporters');
// returning the promise makes protractor wait for the reporter config before executing tests
return browser.getProcessedConfig().then(function () {
// you could use other properties here if you want, such as platform and version
var browserName = 'browser';
browser.getCapabilities().then(function (caps) {
browserName = caps.caps_.browserName.replace(/ /g, "_");
var junitReporter = new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
savePath: testDir,
// this will produce distinct xml files for each capability
filePrefix: 'test-protractor-' + browserName,
modifySuiteName: function (generatedSuiteName) {
// this will produce distinct suite names for each capability,
// e.g. 'firefox.login tests' and 'chrome.login tests'
return 'test-protractor-' + browserName + '.' + generatedSuiteName;
}
});
jasmine.getEnv().addReporter(junitReporter);
});
});
},
baseUrl: 'http://localhost:3000',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: [paths.e2e + '/**/*.js'],
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000
}
};
The error is:
[13:27:13] E/launcher - Error: Error
at C:\ws\node_modules\protractor\built\util.js:55:37
at _rejected (C:\ws\node_modules\q\q.js:844:24)
at C:\ws\node_modules\q\q.js:870:30
at Promise.when (C:\ws\node_modules\q\q.js:1122:31)
at Promise.promise.promiseDispatch (C:\ws\node_modules\q\q.js:788:41)
at C:\ws\node_modules\q\q.js:604:44
at runSingle (C:\ws\node_modules\q\q.js:137:13)
at flush (C:\ws\node_modules\q\q.js:125:13)
at nextTickCallbackWith0Args (node.js:420:9)
at process._tickCallback (node.js:349:13)
[13:27:13] E/launcher - Process exited with error code 100

onPrepare is being evaluated in built/util.js in the runFilenameOrFn_ function. The stacktrace unfortunately is not helpful but what this means is that onPrepare has errors. Looking at your onPrepare method, the error is made when assigning the browserName from the browser capabilities. In your code, caps.caps_ is actually undefined. Because caps.caps_ is undefined, caps.caps_.browserName is throwing an error. The capabilities object should be accessed as the following:
browser.getCapabilities().then(capabilities => {
let browserName = capabilities.browserName.replace(/ /g, "_");

Related

Error while running stubby4node using Gulp

I am trying to setup Stubby Server in my JavaScript environment and I am getting the error below.
The relevant part of my Gulpfile:
gulp.task('stubby', function(cb) {
var options = {
callback: function (server, options) {
server.get(1, function (err, endpoint) {
if (!err)
console.log(endpoint);
});
},
stubs: 8000,
tls: 8443,
admin: 8010,
files: [
'*.*'
]
};
stubby(options, cb);
});
The error:
[12:15:03] Starting 'stubby'...
[12:15:03] 'stubby' errored after 17 ms
[12:15:03] Error: Missing error message
at new PluginError (C:\Users\admin\IdeaProjects\myproject\node_modules\gulp-util\lib\PluginError.js:73:28)
at readJSON (C:\Users\admin\IdeaProjects\myproject\node_modules\gulp-stubby-server\index.js:90:15)
at C:\Users\admin\IdeaProjects\myproject\node_modules\gulp-stubby-server\index.js:149:24
at Array.map (native)
at stubbyPlugin (C:\Users\admin\IdeaProjects\myproject\node_modules\gulp-stubby-server\index.js:136:12)
at Gulp.<anonymous> (C:\Users\admin\IdeaProjects\myproject\gulpfile.js:54:5)
at module.exports (C:\Users\admin\IdeaProjects\myproject\node_modules\orchestrator\lib\runTask.js:34:7)
at Gulp.Orchestrator._runTask (C:\Users\admin\IdeaProjects\myproject\node_modules\orchestrator\index.js:273:3)
at Gulp.Orchestrator._runStep (C:\Users\admin\IdeaProjects\myproject\node_modules\orchestrator\index.js:214:10)
at Gulp.Orchestrator.start (C:\Users\admin\IdeaProjects\myproject\node_modules\orchestrator\index.js:134:8)
Searching the gulp-stubby-server codebase for PluginError yields the follow snippet:
function readJSON(filepath, options) {
var src = fs.readFileSync(filepath, options),
result;
if (!options.mute) {
gutil.log(gutil.colors.yellow('Parsing ' + filepath + '...'));
}
try {
result = JSON.parse(src);
return result;
} catch (e) {
throw new gutil.PluginError(PLUGIN_NAME, 'Unable to parse "' + filepath + '" file (' + e.message + ').', e);
}
}
— Source on GitHub
You can tell this is the likely culprit because of the stack trace you see, where the PluginError is coming from readJSON.
The issue
Take note of the catch block. This is caused by one of the files matching your glob (*.*) not being a valid JSON file.
To fix
Ensure you are using the newest version of gulp-stubby-server
Ensure that you are using the correct glob (that is, do you really mean *.*)
Ensure that all the files in the current working directory are valid JSON files

ws how to catch : WebSocket connection to 'ws:// failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

i have simple web sockets html5 , when the server is up every thing is working fine
the problem is when i close the server ( for testing )
im getting :
WebSocket connection to 'ws://127.0.0.1:7777/api' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
which i unable to catch its never jumps to onerror or onclose in case of this error
init: function () {
this.m_wsiSendBinary = new WebSocket("ws://127.0.0.1:7681/wsapi");
this.m_wsiSendBinary.onopen = function(evt) {
cc.log("Send Binary WS was opened.");
};
this.m_wsiSendBinary.onmessage = (function(evt) {
this.handleServerResponse(yStr);
this.m_wsiSendBinary.onerror = function(evt) {
};
this.m_wsiSendBinary.onclose = function(evt) {
cc.log("m_wsiSendBinary websocket instance closed.");
self.m_wsiSendBinary = null;
};
}).bind(this);
I do not have full answer, however I dealt with similar issue and have a partial and not so elegant solution (but may help someone). Unfortunately without the elimination of the error message.
Two business requirements:
BR1 - Handle state in initialization when the server is not available.
BR2 - Handle state when the server stops.
Solution for BR1
var global_connection_openned=null;//Here you have the result
init: function () {
global_connection_openned=false;
this.m_wsiSendBinary = new WebSocket("ws://127.0.0.1:7681/wsapi");
this.m_wsiSendBinary.onopen = function(evt)
{
global_connection_openned=true;
};
Solution for BR2 (assumes the BR1)
//somewhere in your project called by setInterval(..) which will detect the connection is lost (and tries to reestablish/reopen the connetion.
{
if (this.m_wsiSendBinary==null || this.m_wsiSendBinary.readyState==3)
this.init();
if (!global_connection_openned)
this.m_wsiSendBinary=null;
}
Anyway, I would be really curious if there is solid and proper solution of this use case.

How to use trace.json written by ChromeDriver

I am running a simple node script which starts chromedriver pointed at my website, scrolls to the bottom of the page, and writes the trace to trace.json.
This file is around 30MB.
I can't seem to load this file in chrome://tracing/, which is what I assume I would do in order to view the profile data.
What are my options for making sense of my trace.json file?
Here is my node script, in case that helps clarify what I am up to:
'use strict';
var fs = require('fs');
var wd = require('wd');
var b = wd.promiseRemote('http://localhost:9515');
b.init({
browserName: 'chrome',
chromeOptions: {
perfLoggingPrefs: {
'traceCategories': 'toplevel,disabled-by-default-devtools.timeline.frame,blink.console,disabled-by-default-devtools.timeline,benchmark'
},
args: ['--enable-gpu-benchmarking', '--enable-thread-composting']
},
loggingPrefs: {
performance: 'ALL'
}
}).then(function () {
return b.get('http://www.example.com');
}).then(function () {
// We only want to measure interaction, so getting a log once here
// flushes any previous tracing logs we have.
return b.log('performance');
}).then(function () {
// Smooth scroll to bottom.
return b.execute(`
var height = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight, document.documentElement.clientHeight);
chrome.gpuBenchmarking.smoothScrollBy(height, function (){});
`);
}).then(function () {
// Wait for the above action to complete.
return b.sleep(5000);
}).then(function () {
// Get all the trace logs since last time log('performance') was called.
return b.log('performance');
}).then(function (data) {
// Write the file to disk.
return fs.writeFileSync('trace.json', JSON.stringify(data.map(function (s) {
return JSON.parse(s.message); // This is needed since Selenium outputs logs as strings.
})));
}).fin(function () {
return b.quit();
}).done();
Your script doesn't generate the correct format. The required data for each entry are located in message.message.params.
To generate a trace that can be loaded in chrome://tracing :
var fs = require('fs');
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder()
.withCapabilities({
browserName : 'chrome',
loggingPrefs : { performance: 'ALL' },
chromeOptions : {
args: ['--enable-gpu-benchmarking', '--enable-thread-composting'],
perfLoggingPrefs: {
'traceCategories': 'toplevel,disabled-by-default-devtools.timeline.frame,blink.console,disabled-by-default-devtools.timeline,benchmark'
}
}
}).build();
driver.get('https://www.google.com/ncr');
driver.sleep(1000);
// generate a trace file loadable in chrome://tracing
driver.manage().logs().get('performance').then(function (data) {
fs.writeFileSync('trace.json', JSON.stringify(data.map(function (d) {
return JSON.parse(d['message'])['message']['params'];
})));
});
driver.quit();
The same script with python:
import json, time
from selenium import webdriver
driver = webdriver.Chrome(desired_capabilities = {
'loggingPrefs': { 'performance': 'ALL' },
'chromeOptions': {
"args" : ['--enable-gpu-benchmarking', '--enable-thread-composting'],
"perfLoggingPrefs" : {
"traceCategories": "toplevel,disabled-by-default-devtools.timeline.frame,blink.console,disabled-by-default-devtools.timeline,benchmark"
}
}
})
driver.get('https://stackoverflow.com')
time.sleep(1)
# generate a trace file loadable in chrome://tracing
with open(r"trace.json", 'w') as f:
f.write(json.dumps([json.loads(d['message'])['message']['params'] for d in driver.get_log('performance')]))
driver.quit()
Not sure if you know, the recommendation lib for parsing those thing is https://github.com/ChromeDevTools/devtools-frontend
Also, recommended categories are __metadata,benchmark,devtools.timeline,rail,toplevel,disabled-by-default-v8.cpu_profiler,disabled-by-default-devtools.timeline,disabled-by-default-devtools.timeline.frame,blink.user_timing,v8.execute,disabled-by-default-devtools.screenshot
It's very old question, but hope this helps new other guys.

Unable to load app with protractor test runner

I am new to AngularJS. I'm trying to run end-to-end tests with Protractor. Currently, I am running my tests from grunt with help from grunt-protractor-runner. My base test looks like the following:
describe('My Tests', function () {
var p = protractor.getInstance();
beforeEach(function () {
});
it('My First Test', function () {
var message = "Hello!";
expect(message).toEqual('Hello!');
});
});
This works just fine. However, it really doesn't test my app. To do that I always want to start in the root of the app. In an attempt to do this, I've updated the above to the following:
describe('My Tests', function () {
var p = protractor.getInstance();
beforeEach(function () {
p.get('#/');
});
it('My First Test', function () {
var message = "Hello!";
expect(message).toEqual('Hello!');
});
});
When this test gets ran, Chrome launches. However, "about:blank" is what gets loaded in the address bar. My app never loads. I've reviewed my protractor.config.js file and it looks correct. It looks like the following:
exports.config = {
allScriptsTimeout: 110000,
seleniumServerJar: './node_modules/protractor/bin/selenium/selenium-server-standalone-2.37.0.jar',
seleniumPort: 1234,
seleniumArgs: [],
seleniumAddress: null,
chromeDriver: './node_modules/protractor/bin/selenium/chromedriver.exe',
capabilities: { 'browserName': 'chrome' },
specs: [ '../tests/**/*.spec.js' ],
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000
}
};
How do I get my app to load into Chrome for the purpose of an integration test via protractor?
Perhaps you've already figured out how to get it working, but if not maybe the following will help (modify the port if necessary of course):
// A base URL for your application under test. Calls to protractor.get()
// with relative paths will be prepended with this.
baseUrl: 'http://localhost:3000'
Add this property to your protractor.config.js file.
Reference: https://github.com/angular/protractor/blob/master/referenceConf.js

Phonegap and Windows Phone 7: IndexOutOfBoundsException

I am having issues moving a phonegap application from Android and iOS to WP8. It seems to be crashing when I try to load some language .JSON files. The versions that I use are phonegap 2.9.0 and jQuery 2.0.3. Everything is working as intended on Android and iOS.
Console output:
'TaskHost.exe' (CLR C:\windows\system32\coreclr.dll: Silverlight AppDomain): Loaded 'C:\windows\system32\System.Runtime.Serialization.ni.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Updating IsolatedStorage for APP:DeviceID :: ********-****-****-****-***********
CordovaBrowser_Navigated :: www/index.html
CommandString : Device/getDeviceInfo/Device899915039/[]
'TaskHost.exe' (CLR C:\windows\system32\coreclr.dll: Silverlight AppDomain): Loaded 'C:\windows\system32\System.ServiceModel.Web.ni.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'TaskHost.exe' (CLR C:\windows\system32\coreclr.dll: Silverlight AppDomain): Loaded 'C:\windows\system32\en-US\mscorlib.debug.resources.dll'. Module was built without symbols.
CommandString : NetworkStatus/getConnectionInfo/NetworkStatus899915040/[]
An exception of type 'System.NotSupportedException' occurred in Microsoft.Phone.ni.dll and wasn't handled before a managed/native boundary
The thread 0x1160 has exited with code 259 (0x103).
The thread 0x80c has exited with code 259 (0x103).
CommandString : DebugConsole/log/DebugConsole899915041/"Received Event: deviceready"
Log:["Received Event: deviceready","DebugConsole899915041"]
The thread 0x8c8 has exited with code 259 (0x103).
CommandString : File/readResourceAsText/File899915042/["localization/nb-NO.json"]
A first chance exception of type 'System.IndexOutOfRangeException' occurred in no.visma.patentstyret.DLL
An exception of type 'System.IndexOutOfRangeException' occurred in no.visma.patentstyret.DLL but was not handled in user code
This is the ajax loading of the language files:
var _loadDataSet = function(callback) {
$.ajax({url: "localization/" + _language + ".json", async: false, dataType: 'json', success: function(data) {
_dataSet = data;
if(callback) {
callback();
}
}}).error(function(e) {
console.error("Error in language files.");
console.error(e);
});
};
I have no idea where to start, any help would be much appreciated!
Show please your reading from file code.
I was making application with mustache templating engine, and did this:
$.Mustache.load("./templates/about/about-app.tpl")
This didn't load because WP8 requres full path:
$.Mustache.load("www/templates/about/about-app.tpl")
By the way, WP7 - doesn't load with full path, only with relative =)))
And another thing:
$.ajax({url: "www/localization/" + _language + ".json", async: false, dataType: 'json', success: function(data) {
WP projects don't like extensions like json and others ( sometimes it did work, sometimes didn't NO IDEA WHY ), so i suggest you do:
1) Change file type to *.txt
2) Request:
$.ajax({url: "www/localization/" + _language + ".txt", async: false, dataType: 'text', success: function(data) {
UPDATE:
Almost forgot, to use AJAX you must do this:
document.addEventListener('deviceready', function() {
jQuery.support.cors = true;
$.mobile.allowCrossDomainPages = true;
}, false);
The solution was to use XMLHttpRequest. Tested and works on Android, iPhone and Windows Phone 8. While the solution for loading the local language files was to add the data to a JavaScript class, there were still problems with cross domain requests with PhoneGap on WP8.
To achieve cross domain requests on WP8, I used XMLHttpRequests(Could also use JSONP, but this also supports other formats). This is the wrapper class that I ended up using:
(function() {
name.of.package.HTTPRequest = function(destination, success, error, contentType) {
var STATUS_IDLE = 0;
var STATUS_OPEN = 1;
var STATUS_LOADED = 2;
var STATUS_WORKING = 3;
var STATUS_DONE = 4;
var req = new XMLHttpRequest();
req.open('GET', destination, true);
if(contentType) {
req.setRequestHeader("Content-Type", contentType);
}
else {
req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
}
req.onreadystatechange = function(aEvt) {
if(req.readyState == STATUS_DONE) {
if(req.status == 200) {
if(success) {
success(req.responseText);
}
}
else {
if(error) {
error("Response returned with error code: " + req.status);
}
}
}
};
req.send(null);
};
}) ();