I am trying to set the browser name with protractor test suite name. Because I am using allure reporter for test report. But the problem is I am getting browser name 'undefined' all the time. So far I have implemented browser name in an asynchronous method and I would like to use that method in suitstarted. the suitstarted method is synchronous. I cannot set suit started to asynchronous. In that way how can I wait suitstarted method and get the browser name after the suit.fullname. I am really stuck with this issue from last three days hence I am very new in Javascript.
Here is my code
require('protractor/built/logger').Logger.logLevel = 3;
exports.config = {
sync: false,
multiCapabilities:[
{
'browserName' : 'chrome',
'chromeOptions': { 'args' : ['--disable-extensions']},
'shardTestFiles': true,
'maxInstances': 1,
'unexpectedAlertBehaviour' : 'accept'
},
{
'browserName' : 'firefox',
},
{
'browserName': 'internet explorer',
'se:ieOptions': {
ignoreProtectedModeSettings: true,
'ie.ensureCleanSession': true,
}
},
],
jvmArgs: ['-Dwebdriver.ie.driver=./node_modules/webdriver-manager/selenium/IEDriverServer3.141.0.exe'],
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
isVerbose: true,
showColors: true,
defaultTimeoutInterval: 1500000
},
useAllAngular2AppRoots: true,
beforeLaunch: function() {
},
onPrepare: function() {
// ------------------------------------------------------
var Allure = require('allure-js-commons');
var path = require('path');
var allure = new Allure();
var AllureReporter = function CustomJasmine2AllureReporter(userDefinedConfig, allureReporter) {
var Status = {PASSED: 'passed', FAILED: 'failed', BROKEN: 'broken', PENDING: 'pending'};
this.allure = allureReporter || allure;
this.configure = function(userDefinedConfig) {
var pluginConfig = {};
userDefinedConfig = userDefinedConfig || {};
pluginConfig.resultsDir = userDefinedConfig.resultsDir || 'allure-results';
pluginConfig.basePath = userDefinedConfig.basePath || '.';
var outDir = path.resolve(pluginConfig.basePath, pluginConfig.resultsDir);
this.allure.setOptions({targetDir: outDir});
};
this.configure(userDefinedConfig);
var browserNameforSuit;
Edited
this.suiteStarted = function(suite) {
var capsPromise = browser.getCapabilities();
capsPromise.then(function (caps) {
browserNameforSuit = caps.get('browserName');
console.log(browserNameforSuit)
this.allure.startSuite(suite.fullName);
console.log(suite.fullName);
})
};
};
this.suiteDone = function() {
this.allure.endSuite();
};
this.specStarted = function(spec) {
this.allure.startCase(spec.description);
};
this.specDone = function(spec) {
var status = this._getTestcaseStatus(spec.status);
var errorInfo = this._getTestcaseError(spec);
this.allure.endCase(status, errorInfo);
};
this._getTestcaseStatus = function(status) {
if (status === 'disabled' || status === 'pending') {
return Status.PENDING;
} else if (status === 'passed') {
return Status.PASSED;
} else {
return Status.FAILED;
}
};
this._getTestcaseError = function(result) {
if (result.status === 'disabled') {
return {
message: 'This test was ignored',
stack: ''
};
} else if (result.status === 'pending') {
return {
message: result.pendingReason,
stack: ''
};
}
var failure = result.failedExpectations ? result.failedExpectations[0] : null;
if (failure) {
return {
message: failure.message,
stack: failure.stack
};
}
};
}
// ------------------------------------------------------
var Runtime = require('allure-js-commons/runtime');
let gallure = new Runtime(allure);
browser.manage().window().maximize();
require('ts-node').register({
project: 'e2e/tsconfig.json'
});
jasmine.getEnv().addReporter(new AllureReporter ({
resultsDir: 'allure-results'
}));
jasmine.getEnv().addReporter(reporter);
jasmine.getEnv().afterEach(function (done) {
browser.takeScreenshot().then(function (png) {
gallure.createAttachment('Screenshot', function () {
return new Buffer(png, 'base64')
},'image/png')();
done();
})
});
}
};
The index.js for Allure is
'use strict';
var assign = require('object-assign'),
Suite = require('./beans/suite'),
Test = require('./beans/test'),
Step = require('./beans/step'),
Attachment = require('./beans/attachment'),
util = require('./util'),
writer = require('./writer');
function Allure() {
this.suites = [];
this.options = {
targetDir: 'allure-results'
};
}
Allure.prototype.setOptions = function(options) {
assign(this.options, options);
};
Allure.prototype.getCurrentSuite = function() {
return this.suites[0];
};
Allure.prototype.getCurrentTest = function() {
return this.getCurrentSuite().currentTest;
};
Allure.prototype.startSuite = function(suiteName, timestamp) {
this.suites.unshift(new Suite(suiteName,timestamp));
};
Allure.prototype.endSuite = function(timestamp) {
var suite = this.getCurrentSuite();
suite.end(timestamp);
if(suite.hasTests()) {
writer.writeSuite(this.options.targetDir, suite);
}
this.suites.shift();
};
// other methods
module.exports = Allure;
And the Suit.js is
function Suite(name, timestamp){
this.name = name;
this.start = timestamp || Date.now();
this.testcases = [];
}
Suite.prototype.end = function(timestamp) {
this.stop = timestamp || Date.now();
};
Suite.prototype.hasTests = function() {
return this.testcases.length > 0;
};
Suite.prototype.addTest = function(test) {
this.testcases.push(test);
};
Suite.prototype.toXML = function() {
var result = {
'#': {
'xmlns:ns2' : 'urn:model.allure.qatools.yandex.ru',
start: this.start
},
name: this.name,
title: this.name,
'test-cases': {
'test-case': this.testcases.map(function(testcase) {
return testcase.toXML();
})
}
};
if(this.stop) {
result['#'].stop = this.stop;
}
return result;
};
module.exports = Suite;
How can I set browserName at the end of the suit.fullname. Is there any alternative way to do that.
Error
Test Suites & Specs:
1. 0030 Test for correct login
No specs found
Finished in 0.017 seconds
An error was thrown in an afterAll
AfterAll TypeError: Cannot read property 'end' of undefined
>> Done!
Summary:
Finished in 0.017 seconds
chrome
[13:23:03] E/launcher - Cannot read property 'startSuite' of undefined
[13:23:03] E/launcher - TypeError: Cannot read property 'startSuite' of
undefined
at C:\Users\mnowshin\projects\beck-hb\hb-frontend\protractor.mn.conf.js:130:18
at ManagedPromise.invokeCallback_ (\node_modules\selenium-webdriver\lib\promise.js:1376:14)
at TaskQueue.execute_ (\node_modules\selenium-webdriver\lib\promise.js:3084:14)
at TaskQueue.executeNext_ (\node_modules\selenium-webdriver\lib\promise.js:3067:27)
at asyncRun (\node_modules\selenium-webdriver\lib\promise.js:2927:27)
at \node_modules\selenium-webdriver\lib\promise.js:668:7
at process.internalTickCallback (internal/process/next_tick.js:77:7)
[13:23:03] E/launcher - Process exited with error code 199
Process finished with exit code 199
so I don't work with allure, but I can show you how I get the browser name and then you can try to apply to your case.
Try to change from this:
var browserNameforSuit;
let bName = (async () => {
try {
browserNameforSuit = (await browser.getCapabilities()).get('browserName');
return browserNameforSuit;
} catch (err) {
return "Error or smth"
}
})();
To this:
var capsPromise = browser.getCapabilities();
var browserNameforSuit;
capsPromise.then(function (caps) {
browserNameforSuit = caps.get('browserName');
//if you need you can return the result to a var in order to user somewhere else
});
This is the onComplete from my conf.js
onComplete: function()
{
var browserName, browserVersion;
var capsPromise = browser.getCapabilities();
capsPromise.then(function (caps) {
browserName = caps.get('browserName');
browserVersion = caps.get('version');
platform = caps.get('platform');
//here I prepare the testConfig adding what I need//
//here I get the xml with the test results and create an html
new HTMLReport().from('./execution_results/reports/xml/xmlresults.xml', testConfig);
});//End Of capsPromise
},
Hope it helps!
Related
I am working on Custom speech in bot framework.I add Bing simple speech it is working on my website: here is link :https://envolvebot.azurewebsites.net/
but now i want to know how can we add custom speech (LUIS custom speech) in our webchat bot?
I create custom speech using : https://westus.cris.ai/Home/CustomSpeech
Now i want to add it and want it to work like bing speech .
i am using following code.
/*! modernizr 3.6.0 (Custom Build) | MIT *
* https://modernizr.com/download/?-getusermedia-speechsynthesis !*/
!function (e, n, s) { function i(e, n) { return typeof e === n } function o() { var e, n, s, o, a, f, d; for (var c in t) if (t.hasOwnProperty(c)) { if (e = [], n = t[c], n.name && (e.push(n.name.toLowerCase()), n.options && n.options.aliases && n.options.aliases.length)) for (s = 0; s < n.options.aliases.length; s++)e.push(n.options.aliases[s].toLowerCase()); for (o = i(n.fn, "function") ? n.fn() : n.fn, a = 0; a < e.length; a++)f = e[a], d = f.split("."), 1 === d.length ? Modernizr[d[0]] = o : (!Modernizr[d[0]] || Modernizr[d[0]] instanceof Boolean || (Modernizr[d[0]] = new Boolean(Modernizr[d[0]])), Modernizr[d[0]][d[1]] = o), r.push((o ? "" : "no-") + d.join("-")) } } var t = [], a = { _version: "3.6.0", _config: { classPrefix: "", enableClasses: !0, enableJSClass: !0, usePrefixes: !0 }, _q: [], on: function (e, n) { var s = this; setTimeout(function () { n(s[e]) }, 0) }, addTest: function (e, n, s) { t.push({ name: e, fn: n, options: s }) }, addAsyncTest: function (e) { t.push({ name: null, fn: e }) } }, Modernizr = function () { }; Modernizr.prototype = a, Modernizr = new Modernizr, Modernizr.addTest("speechsynthesis", "SpeechSynthesisUtterance" in e), Modernizr.addTest("getUserMedia", "mediaDevices" in navigator && "getUserMedia" in navigator.mediaDevices); var r = []; o(), delete a.addTest, delete a.addAsyncTest; for (var f = 0; f < Modernizr._q.length; f++)Modernizr._q[f](); e.Modernizr = Modernizr }(window, document);
// Necessary for safari
// Safari will only speak after speaking from a button click
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
const params = BotChat.queryParams(location.search);
debugger;
function SpeakText() {
var msg = new SpeechSynthesisUtterance();
window.speechSynthesis.speak(msg);
document.getElementsByClassName("wc-mic")[0].removeEventListener("click", SpeakText);
}
if (isSafari) {
window.addEventListener("load", function () {
document.getElementsByClassName("wc-mic")[0].addEventListener("click", SpeakText);
});
}
var femaleVoice = null;
if (Modernizr.speechsynthesis) {
var baseSpeechPrototype = SpeechSynthesisUtterance.prototype;
SpeechSynthesisUtterance = function (msg) {
var utterance = new baseSpeechPrototype.constructor(msg);
if (femaleVoice != null)
utterance.voice = femaleVoice;
return utterance;
}
window.speechSynthesis.onvoiceschanged = function () {
var voice = "Microsoft Zira";
var safariVoice = "Samantha";
var voices = window.speechSynthesis.getVoices();
voices.forEach(function (v) {
if (v.name.startsWith(voice))
femaleVoice = v;
else if (v.name == safariVoice && v.lang == "en-US")
femaleVoice = v;
})
}
}
//// Needed to change between the two audio contexts
var AudioContext = window.AudioContext || window.webkitAudioContext;
//// Sets the old style getUserMedia to use the new style that is supported in more browsers even though the framework uses the new style
if (window.navigator.mediaDevices.getUserMedia && !window.navigator.getUserMedia) {
window.navigator.getUserMedia = function (constraints, successCallback, errorCallback) {
window.navigator.mediaDevices.getUserMedia(constraints)
.then(function (e) {
successCallback(e);
})
.catch(function (e) {
errorCallback(e);
});
};
}
const bot = {
id: params['botid'] || 'botid',
name: params['botname'] || 'botname'
};
window.botchatDebug = params['debug'] && params['debug'] === 'true';
var speechOptions;
if (Modernizr.speechsynthesis) {
speechOptions = {
speechRecognizer: new CognitiveServices.SpeechRecognizer({
fetchCallback: function (authFetchEventId) { return getBingToken() },
fetchOnExpiryCallback: function (authFetchEventId) { getBingToken() }
}),
speechSynthesizer: new BotChat.Speech.BrowserSpeechSynthesizer()
};
}
else if (Modernizr.getusermedia) {
speechOptions = {
speechRecognizer: new CognitiveServices.SpeechRecognizer({
fetchCallback: function (authFetchEventId) { return getBingToken() },
fetchOnExpiryCallback: function (authFetchEventId) { getBingToken() }
}),
speechSynthesizer: null
};
}
else {
speechOptions = null;
}
// for bot
var botConnection = new BotChat.DirectLine({
domain: params['domain'],
//token: document.getElementById("directLineToken").value,
secret: 'Secret',
webSocket: params['webSocket'] && params['webSocket'] === 'true' // defaults to true
});
BotChat.App({
sendTyping: true,
locale: params['locale'],
resize: 'detect',
speechOptions: speechOptions,
user: { id:'ID' name: "You" },
bot: { id: 'Vera', name: "Vera" },
botConnection: botConnection
}, document.getElementById('BotChatElement'));
function getBingToken() {
// Normally this token fetch is done from your secured backend to avoid exposing the API key and this call
// would be to your backend, or to retrieve a token that was served as part of the original page.
return fetch(
'https://api.cognitive.microsoft.com/sts/v1.0/issueToken',
{
headers: {
'Ocp-Apim-Subscription-Key': 'Key'
},
method: 'POST'
}
//).then(res => res.text());
).then(function (res) { return res.text() });
}
aNY BODY Know how to do this ?
Thank in advance .
Service
angular.module('App').service('producerContactSvc', ['$http', 'configSvc', function($http, configSvc) {
//Reset headers to avoid OPTIONS request (aka preflight)
$http.defaults.headers.common = {};
var _this = this;
_this.getProducerContacts = function(producerId) {
var endpoint = configSvc.backendUrl + '/producerContact/read?producerId=' + producerId;
return $http.get(endpoint)
.then(function(response) {
return response.data;
})
.catch(function(response) {
return response.data;
});
};
_this.addProducerContact = function(producerContact) {
var endpoint = configSvc.backendUrl + '/producerContact/create';
return $http.post(endpoint, producerContact)
.success(function(response) {
return response.data;
})
.catch(function(response) {
return response.data;
});
};
_this.deleteProducerContact = function(producerContactId, producerId) {
var endpoint = configSvc.backendUrl + '/producerContact/delete?producerContactId=' + producerContactId + '&' + 'producerId=' + producerId;
return $http.delete(endpoint)
.then(function(response) {
return response.data;
})
.catch(function(response) {
return response.data;
});
};
_this.updateProducerContact = function(producerContact) {
var endpoint = configSvc.backendUrl + '/producerContact/update';
return $http.put(endpoint, producerContact)
.then(function(response) {
return response.data;
})
.catch(function(response) {
return response.data;
});
};
}]);
Controller
angular.module('App').controller('producerAdminCtrl', ['$scope', '$rootScope', 'producerSvc', '$mdDialog', 'producerContactSvc', 'errorToastSvc', function($scope, $rootScope, producerSvc, $mdDialog, producerContactSvc, errorToastSvc) {
$scope.results = false;
$scope.producerTypeCodes = ['CX', 'FG'];
$scope.producerId = null;
$scope.documents = [];
$scope.selectedDocs = [];
$scope.producerContactRows = [];
$scope.missingName = false;
$scope.producerContactTypeCodes = ['MC', 'BC'];
/**
* Get a list of all producers on load
*/
producerSvc.getAllProducers()
.then(function(response) {
if (response !== null) {
$scope.unusedProducers = response.data;
} else {
$scope.noFound = true;
$scope.results = false;
$scope.message = 'No Data Received';
}
});
/**
* Perform a search on a producer. This will call the backend and find information about the producer searched for
*/
$scope.search = function() {
$scope.documents = [];
$scope.selectedDocs = [];
$scope.query = $scope.selectedItem.producerId;
producerSvc.getProducer($scope.query).then(function(response) {
if (response && response.data) {
$scope.producer = response.data;
$scope.producerId = $scope.query;
$scope.producer.inactiveDate = response.data.inactiveDate === null ? null : new Date(response.data.inactiveDate);
producerSvc.getAllDocs().then(function(response) {
_.forEach(response, function(doc) {
var docObject = {
documentId: doc.documentId,
documentDescription: doc.documentDescription,
documentName: doc.documentName,
selected: false
};
$scope.documents.push(docObject);
});
producerSvc.getProducerDocs($scope.producerId).then(function(response2) {
_.forEach(response2.data, function(docProducer) {
var docId = docProducer.documentId;
_.forEach($scope.documents, function(doc) {
if (docId === doc.documentId) {
doc.selected = true;
$scope.selectedDocs.push(doc);
}
});
});
$scope.documents.sort(function(x, y) {
return (x.selected === y.selected) ? 0 : x.selected ? -1 : 1;
});
$scope.results = true;
$scope.noFound = false;
});
});
} else {
$scope.noFound = true;
$scope.results = false;
$scope.message = 'No Producer Found';
}
});
producerContactSvc.getProducerContacts($scope.query).then(function(response) {
_.forEach(response, function(producerContact) {
var producerContactObject = {
producerContactName: producerContact.producerContactName,
editable: false,
producerContactEmail: producerContact.producerContactEmail,
producerContactType: producerContact.producerContactType,
invalid: false,
producerContactIsNew: false,
producerContactId: producerContact.producerContactId,
producerId: producerContact.producerId
};
$scope.producerContactRows.push(producerContactObject);
});
});
/**
* Add a new producerContact to the producerContactRows array.
*/
$scope.addProducerContact = function() {
var producerId = '';
var producerContactName = '';
var producerContactEmail = '';
var producerContactType = '';
var producerContactObject = {
producerId: producerId,
producerContactName: producerContactName,
editable: true,
producerContactEmail: producerContactEmail,
producerContactType: producerContactType,
invalid: false,
producerContactIsNew: true
};
$scope.producerContactRows.push(producerContactObject);
};
/**
* Enable edit mode on a selected producerContact.
* #param {number} producerContactIndex the index within the producerContactRows array of the producerContact to edit.
*/
$scope.editProducerContact = function(producerContactIndex) {
$scope.producerContactRows[producerContactIndex].editable = true;
};
/**
* Save a selected producerContact.
* #param {number} producerContactIndex the index within the producerContactRows array of the producerContact to save.
*/
$scope.saveProducerContact = function(producerContactIndex) {
if ($scope.producerContactRows[producerContactIndex].producerContactIsNew) {
producerContactSvc.addProducerContact($scope.sanitizeProducerContact($scope.producerContactRows[producerContactIndex])).then(function(response) {
$scope.producerContactRows[producerContactIndex].producerContactId = response.data.producerContactId;
});
$scope.producerContactRows[producerContactIndex].producerContactIsNew = false;
} else {
producerContactSvc.updateProducerContact($scope.sanitizeProducerContact($scope.producerContactRows[producerContactIndex]));
}
$scope.producerContactRows[producerContactIndex].editable = false;
};
/**
* Prompt the user for confirmation they want to delete a producerContact.
* #param {number} producerContactIndex the index within the producerContactRows array of the producerContact to delete.
*/
$scope.deleteProducerContact = function(producerContactIndex, ev) {
var deleteProducerContact = $mdDialog.confirm()
.title('Are you sure you want to delete this ProducerContact?')
.ariaLabel('Delete ProducerContact')
.targetEvent(ev)
.ok('Delete ProducerContact')
.cancel('Cancel');
$mdDialog.show(deleteProducerContact).then(function() {
$scope.performDelete(producerContactIndex);
});
};
/**
* Delete a selected producerContact after verification.
* #param {number} producerContactIndex the index within the producerContactRows array of the producerContact to delete.
*/
$scope.performDelete = function(producerContactIndex) {
console.log($scope.producerContactRows[producerContactIndex]);
if (!$scope.producerContactRows[producerContactIndex].producerContactIsNew) {
producerContactSvc.deleteProducerContact($scope.producerContactRows[producerContactIndex].producerContactId, $scope.producerId);
}
$scope.producerContactRows.splice(producerContactIndex, 1);
};
/**
* Save the producer information to the backend
*/
$scope.saveProducer = function() {
var docObjects = [];
var timestamp = new Date().getTime();
var user = null;
if ($rootScope.apmHeader) {
user = $rootScope.apmHeader.userI;
}
_.forEach($scope.selectedDocs, function(doc) {
var docObject = {
documentid: doc.documentId,
producerId: $scope.producerId,
approvedby: user,
dateapproved: timestamp
};
docObjects.push(docObject);
});
$scope.producer.documentList = docObjects;
producerSvc.saveProducerInfo($scope.producer);
};
}]);
Test Class
describe('Test Producer Contact', function() {
//Add an initialize here:
var $scope;
var $rootScope;
var controller;
// deferred variables
var getProducerDefer;
var getProducerContactsDefer;
var addProducerContactDefer;
var updateProducerContactDefer;
var deleteProducerContactDefer;
var producerContactSvc;
var mockProducerContacts = [{
producerContactId: '11111',
producerId: '1111',
producerContactName: 'abcd',
producerContactEmail: 'abcd#abc.com',
producerContactType: 'cc',
editable: false,
invalid: false,
producerContactIsNew: false
},
{
producerContactId: '11112',
producerId: '1111',
producerContactName: 'efgh',
producerContactEmail: 'efgh#xyc.com',
producerContactType: 'primary',
editable: false,
invalid: false,
producerContactIsNew: false
},
{
producerContactId: '12345',
producerId: '1111',
producerContactName: 'asdh',
producerContactEmail: 'asdh#xyc.com',
producerContactType: 'cc',
editable: false,
invalid: false,
producerContactIsNew: false
}
];
beforeEach(module('FirstSaleApp'));
beforeEach(inject(function($controller, producerSvc, producerContactSvc, _$q_, _$rootScope_) {
$scope = _$rootScope_.$new();
$rootScope = _$rootScope_;
producerContactSvc.deleteProducerContact = function() {
return null;
};
// We use the $q service to create a mock instance of defer
getProducerDefer = _$q_.defer();
getProducerContactsDefer = _$q_.defer();
addProducerContactDefer = _$q_.defer();
updateProducerContactDefer = _$q_.defer();
deleteProducerContactDefer = _$q_.defer();
// Use a Jasmine Spy to return the deferred promise
spyOn(producerSvc, 'getAllProducers').and.returnValue(getProducerDefer.promise);
spyOn(producerContactSvc, 'getProducerContacts').and.returnValue(getProducerContactsDefer.promise);
spyOn(producerContactSvc, 'addProducerContact').and.returnValue(addProducerContactDefer.promise);
spyOn(producerContactSvc, 'updateProducerContact').and.returnValue(updateProducerContactDefer.promise);
spyOn(producerContactSvc, 'deleteProducerContact').and.returnValue(deleteProducerContactDefer.promise);
$controller('producerAdminCtrl', {
$scope: $scope,
producerSvc: producerSvc,
producerContactSvc: producerContactSvc
});
// getProducerDefer.resolve(mockProducers);
getProducerContactsDefer.resolve(mockProducerContacts);
// $scope.$digest();
$rootScope.$digest();
}));
it('controller exists', function() {
expect(controller).not.toBeNull();
});
it('should get the producerContacts from the producerContact service', function() {
// $scope.producerContactRows = $scope.getProducerContacts(1111);
// The length should match
expect($scope.producerContactRows.length).toBe(3); // <-- coming as 0
// The values should be the same too
// Mock 1
expect($scope.producerContactRows[0].producerContactName).toBe(mockProducerContacts[0].producerContactName);
expect($scope.producerContactRows[0].producerContactEmail).toBe(mockProducerContacts[0].producerContactEmail);
expect($scope.producerContactRows[0].producerContactType).toBe(mockProducerContacts[0].producerContactType);
expect($scope.producerContactRows[0].editable).toBeFalsy();
expect($scope.producerContactRows[0].producerContactIsNew).toBeFalsy();
// Mock 2
expect($scope.producerContactRows[1].producerContactName).toBe(mockProducerContacts[1].producerContactName);
expect($scope.producerContactRows[1].producerContactEmail).toBe(mockProducerContacts[1].producerContactEmail);
expect($scope.producerContactRows[1].producerContactType).toBe(mockProducerContacts[1].producerContactType);
expect($scope.producerContactRows[1].editable).toBeFalsy();
expect($scope.producerContactRows[1].producerContactIsNew).toBeFalsy();
// Mock 3
expect($scope.producerContactRows[2].producerContactName).toBe(mockProducerContacts[2].producerContactName);
expect($scope.producerContactRows[2].producerContactEmail).toBe(mockProducerContacts[2].producerContactEmail);
expect($scope.producerContactRows[2].producerContactType).toBe(mockProducerContacts[2].producerContactType);
expect($scope.producerContactRows[2].editable).toBeFalsy();
expect($scope.producerContactRows[2].producerContactIsNew).toBeFalsy();
});
});
I'm new to angularjs - I have started working on an app that uses karma and jasmine to test. I am trying to use deferred promise to stub a method call. However I don't see the data after I digest (or apply) the scope. Any help is appreciated on what I might be missing. Thanks
I am using an extension of HashLocation to implement a hashbang url type for Ember.js.
Here is the code snippet:
(function() {
var get = Ember.get, set = Ember.set;
Ember.Location.registerImplementation('hashbang', Ember.HashLocation.extend({
getURL: function() {
return get(this, 'location').hash.substr(2);
},
setURL: function(path) {
get(this, 'location').hash = "!"+path;
set(this, 'lastSetURL', "!"+path);
},
onUpdateURL: function(callback) {
var self = this;
var guid = Ember.guidFor(this);
Ember.$(window).bind('hashchange.ember-location-'+guid, function() {
Ember.run(function() {
var path = location.hash.substr(2);
if (get(self, 'lastSetURL') === path) { return; }
set(self, 'lastSetURL', null);
callback(location.hash.substr(2));
});
});
},
formatURL: function(url) {
return '#!'+url;
}
}));
})();
I use this by reopening the Router:
App.Router.reopen({
location: 'hashbang'
});
However, on running the application, i'm hitting the following deprecation:
DEPRECATION: Using the Ember.Location.registerImplementation is no longer supported. Register your custom location implementation with the container instead.
I can't find any information on how to do this. Does anyone have any implementation snippets on what I would have to do?
According to deprecation message. use container instead.
(function() {
var get = Ember.get, set = Ember.set;
var hashbangLocation = Ember.HashLocation.extend({
getURL: function() {
return get(this, 'location').hash.substr(2);
},
setURL: function(path) {
get(this, 'location').hash = "!"+path;
set(this, 'lastSetURL', "!"+path);
},
onUpdateURL: function(callback) {
var self = this;
var guid = Ember.guidFor(this);
Ember.$(window).bind('hashchange.ember-location-'+guid, function() {
Ember.run(function() {
var path = location.hash.substr(2);
if (get(self, 'lastSetURL') === path) { return; }
set(self, 'lastSetURL', null);
callback(location.hash.substr(2));
});
});
},
formatURL: function(url) {
return '#!'+url;
}
});
App.register('location:hashbang', hashbangLocation);
})();
Reopen it as usual
App.Router.reopen({
location: 'hashbang'
});
I'm trying to create a button class that extends an AbstractComponent class using $.extend() but the functions in AbstractComponent aren't available when I'm constructing the button.
The specific error I'm receiving is:
Uncaught TypeError: Object [object Object] has no method 'setOptions'
var Button = {};
var abstract = new AbstractComponent;
$.extend(Button,abstract);
//debugger;
//this.setOptions is available here
Button = function(options) {
'use strict';
var defaultOptions = {
templateName: '#button-tmpl',
title: "Label goes here",
type: "primary",
size: "medium",
disabled: null,
autosave: null,
href: null,
onclick: null
};
//debugger
//this.setOptions is not available here
this.setOptions(options, defaultOptions);
this.checkRequiredKeys('title');
return this;
};
Button.prototype.updateOptions = function() {
var options = this.options;
if (options.href === null) {
options.href = 'javascript:;';
}
if (options.disabled === null) {
options.disabled = 'disabled';
}
if (options.autosave === true) {
options.autosave = 'ping-autosave';
}
};
AbstractComponent.js
var AbstractComponent = function() {
console.log('this will be the constructor for elements extending this class');
};
AbstractComponent.prototype.show = function() {
this.render();
};
AbstractComponent.prototype.close = function() {
// stop listeners and remove this component
this.stopListening();
this.remove();
};
AbstractComponent.prototype.getTemplateName = function() {
return this.options.templateName;
};
AbstractComponent.prototype.checkRequiredKeys = function() {
var errors = new Array();
if (typeof this.getTemplateName() === "undefined") {
errors.push('templateName');
}
for (var i = 0; i < arguments.length; i++) {
if (!this.options.hasOwnProperty(arguments[i])) {
errors.push(arguments[i]);
}
}
if (errors.length > 0) {
throw new Exception("Required property(s) not found:" + errors.join(', ') + " in " + this.toString());
}
};
AbstractComponent.prototype.getElement = function() {
'use strict';
if(!this.options.updated) {
this.updateOptions();
}
return new AbstractView(this.options).render().$el;
};
AbstractComponent.prototype.updateOptions = function() {
this.options.updated = true;
return true;
};
AbstractComponent.prototype.getHtml = function() {
return this.getElement().html();
};
AbstractComponent.prototype.setOptions = function(options, defaultOptions) {
this.options = _.defaults(options, defaultOptions);
};
AbstractComponent.prototype.toString = function() {
return "Component" + this.getTemplateName() + "[id=" + this.options.id + "]";
};
jQuery extend is for moving properties from one (or more) object(s) to another object.
$.extend({}, {
foo: 10,
bar: 20
});
You should use prototypal inheritance isntead
function Button(options) {
'use strict';
var defaultOptions = {
templateName: '#button-tmpl',
title: "Label goes here",
type: "primary",
size: "medium",
disabled: null,
autosave: null,
href: null,
onclick: null
};
//debugger
//this.setOptions is not available here
this.setOptions(options, defaultOptions);
this.checkRequiredKeys('title');
return this;
};
Button.prototype = new AbstractComponent;
I have to download myURLString (http://www.google.com/search?q=http://www.google.com/&btnG=Search+Directory&hl=en&cat=gwd%2FTop).
function getcontents(myURLString) {
var gChannel;
var ioService = Components.classes["#mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
var uri = ioService.newURI(myURLString, null, null);
gChannel = ioService.newChannelFromURI(uri);
var listener = new StreamListener(callbackFunc);
gChannel.notificationCallbacks = listener;
gChannel.asyncOpen(listener, null);
function StreamListener(aCallbackFunc) {
this.mCallbackFunc = aCallbackFunc;
}
StreamListener.prototype = {
mData: "",
onStartRequest: function (aRequest, aContext) {
this.mData = "";
},
onDataAvailable: function (aRequest, aContext, aStream, aSourceOffset, aLength) {
var scriptableInputStream = Components.classes["#mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
scriptableInputStream.init(aStream);
this.mData += scriptableInputStream.read(aLength);
},
onStopRequest: function (aRequest, aContext, aStatus) {
if (Components.isSuccessCode(aStatus)) {
this.mCallbackFunc(this.mData);
alert('test');
} else {
this.mCallbackFunc(null);
}
gChannel = null;
},
onChannelRedirect: function (aOldChannel, aNewChannel, aFlags) {
gChannel = aNewChannel;
},
getInterface: function (aIID) {
try {
return this.QueryInterface(aIID);
} catch (e) {
throw Components.results.NS_NOINTERFACE;
}
},
onProgress : function (aRequest, aContext, aProgress, aProgressMax) { },
onStatus : function (aRequest, aContext, aStatus, aStatusArg) { },
onRedirect : function (aOldChannel, aNewChannel) { },
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
aIID.equals(Components.interfaces.nsIChannelEventSink) ||
aIID.equals(Components.interfaces.nsIProgressEventSink) ||
aIID.equals(Components.interfaces.nsIHttpEventSink) ||
aIID.equals(Components.interfaces.nsIStreamListener))
return this;
throw Components.results.NS_NOINTERFACE;
}
};
}
I'm thinking this.mData should have the page's contents, but I can't alert it, so I'm trying first to alert test. What is wrong?
UPDATE: I'm trying now...
function callbackFunc(pagecontents) {
alert(pagecontents);
}
...but it isn't called. Why?
I suspect you are getting an error since StreamListener is defined after you call new StreamListener(...). Have you set the proper developer preferences?