I'm trying to create a background task for my JavaScript Metro app. I added these to the default.js file:
function RegisterBackgroundTask(taskEntryPoint, taskName, trigger, condition) {
// Check for existing registrations of this background task.
var taskRegistered = false;
var background = Windows.ApplicationModel.Background;
var iter = background.BackgroundTaskRegistration.allTasks.first();
var hascur = iter.hasCurrent;
while (hascur) {
var cur = iter.current.value;
if (cur.name === taskName) {
taskRegistered = true;
break;
}
hascur = iter.moveNext();
}
// If the task is already registered, return the registration object.
if (taskRegistered == true) {
return iter.current;
}
// Register the background task.
var builder = new background.BackgroundTaskBuilder();
builder.Name = taskName;
builder.TaskEntryPoint = taskEntryPoint;
builder.setTrigger(trigger);
if (condition != null) {
builder.addCondition(condition);
}
var task = builder.register();
return task;
}
var trigger = new Windows.ApplicationModel.Background.SystemTrigger(Windows.ApplicationModel.Background.SystemTriggerType.timeZoneChange, false);
RegisterBackgroundTask("js\\bgtask.js", "test", trigger);
This is my bgtask.js:
(function () {
"use strict";
var backgroundTaskInstance = Windows.UI.WebUI.WebUIBackgroundTaskInstance.current;
function doWork() {
// Write JavaScript code here to do work in the background.
console.log("task done");
close();
}
doWork();
})();
This is my app manifest:
When I change the timezone, nothing happened. I checked the event log and there is an error:
The background task with entry point and name failed to activate with error code 0x80040154.
What did I do wrong?
builder.Name = taskName;
builder.TaskEntryPoint = taskEntryPoint;
should be
builder.name = taskName;
builder.taskEntryPoint = taskEntryPoint;
Related
I have a command that overwrites pause to add the input from a dialog to the reports. I want to know if there is a way to know what test is calling the function so that I can customize the message on the inputs.
Cypress.Commands.overwrite('pause', (originalFn, element, options) => {
var tryThis = '';
if (//place calling the function == file1) {
tryThis = 'message1';
} else if (//place calling the function == file2) {
...
} else if (//place calling the function == file3) {
...
}
var datalog = window.prompt(tryThis, "Log your results");
cy.addContext("DATALOG:" + datalog);
return originalFn(element, options)
})
As well as access via the Mocha properties there is also
For the spec file Cypress.spec
Properties for my.spec.js
Cypress.spec.absolute: "C:/.../my.spec.js"
Cypress.spec.name: "my.spec.js"
Cypress.spec.relative: "cypress\integration\my.spec.js"
Cypress.spec.specFilter: "my"
Cypress.spec.specType: "integration"
For the test cy.state('runnable')
For
describe('my-context', () => {
it('my-test', () => {
Properties and methods,
const title = cy.state('runnable').title; // "my-test"
const fullTitle = cy.state('runnable').fullTitle(); // "my-context my-test"
const titlePath = cy.state('runnable').titlePath(); // ["my-context", "my-test"]
You can also add metadata to the test
describe('my-context', () => {
it('my-test', { message: "my-message" }, () => {
and grab it in the command overwrite
const message = cy.state('runnable').cfg.message; // "my-message"
I tried this and it worked for me (my version of cypress is 6.1.0):
cy.log(Cypress.mocha.getRunner().suite.ctx.test.title);
More info: https://github.com/cypress-io/cypress/issues/2972
Lately I've been trying to implement WebRTC datachannels in Haxe, but come across a great deal of difficulty. When I use
dataChannel.send();
there appears to be no effect, despite the data channel supposedly being successfully opened.
The (extremely inefficient and messy) code I'm using looks like this:
package arm;
import haxe.Json;
import js.html.rtc.*;
import js.html.Document;
import js.html.WebSocket;
import js.html.DataElement;
#:expose
class DataChannelManager extends iron.Trait {
var user = "gobbledygook";
var first = false;
var initiator = true;
public function new() {
super();
var document = new Document();
var ws:js.html.WebSocket;
var config = {"iceServers":[{"url":"stun:stun.l.google.com:19302"}]};//temporary arrangement
//var optional:Array<Dynamic> = [{'DtlsSrtpKeyAgreement': true}, {'RtcDataChannels': true }];
// var connection:Dynamic = {
// 'optional'://try changing this to mandatory some time
// optional
// };
var peerConnection = new PeerConnection(config);
var dataChannel:js.html.rtc.DataChannel;
var ready = false;
function sendNegotiation(type, sdp) {
var json = {user:user/*, theloc:myloc*/, action: type, data: sdp};
ws.send(Json.stringify(json));
trace("Negotiation of type "+json.action);
}
var sdpConstraints = {
offerToReceiveAudio: false,
offerToReceiveVideo: false
};
var dcOpen=false;
notifyOnInit(function() {
var optionalStruct:Dynamic = {reliable: true}
dataChannel = peerConnection.createDataChannel("datachannel", optionalStruct);
dataChannel.onmessage = function(e){trace("DC message:" +e.data);};
dataChannel.onopen = function(){trace("-DC OPENED");dcOpen=true;};
dataChannel.onclose = function(){trace("-DC closed!");};
dataChannel.onerror = function(){trace("DC ERROR");};
trace("intialization!");
});
var firstfirst=true;
notifyOnUpdate(function() {
if (dcOpen) {
dcOpen=false;
trace("sending...");
dataChannel.send("stuff!");
}
if (firstfirst&&object.properties['go']) {
user=object.properties['string'];
first=true;
firstfirst=false;
// if (initiator) {
// peerConnection.createOffer(sdpConstraints).then(function (sdp) {
// peerConnection.setLocalDescription(sdp);
// sendNegotiation("offer", sdp);
// trace("SEND OFFER");
// }, function (data) {
// trace("Offer creation failure,", data);
// });
// } else {
// peerConnection.createAnswer(sdpConstraints).then(function (sdp) {
// trace("Answer made.");
// peerConnection.setLocalDescription(sdp);
// sendNegotiation("answer", sdp);
// });
// }
}
if (first) {
first=false;
ws = new WebSocket("ws://----------/*yes, there's an ip here*/:8080");
ws.onopen = function() {
trace("ws opened!");
peerConnection.onicecandidate = function(event) {
trace("ICE offer ready");
if (peerConnection==null || event ==null || event.candidate == null) return;
sendNegotiation("candidate", event.candidate);
}
if (initiator) {
trace("initiating");
// var optionalStruct:Dynamic = {reliable: true}
// dataChannel = peerConnection.createDataChannel("datachannel", optionalStruct);
// dataChannel.onmessage = function(e){trace("DC message:" +e.data);};
// dataChannel.onopen = function(){trace("-DC OPENED");dcOpen=true;};
// dataChannel.onclose = function(){trace("-DC closed!");};
// dataChannel.onerror = function(){trace("DC ERROR");};
peerConnection.createOffer(/*sdpConstraints*/).then(function (sdp) {
peerConnection.setLocalDescription(sdp);
sendNegotiation("offer", sdp);
trace("SEND OFFER");
}, function (data) {
trace("Offer creation failure,", data);
});
}
ws.onmessage = function (data) {
//var info=data.data.split()
if (data.data=="connected!") {return;}
var adata = Json.parse(data.data.substring(5));
if (adata.action=="offer") {
trace("Offer recieved.");
// var optionalStruct:Dynamic = {reliable: true}
// dataChannel = peerConnection.createDataChannel("datachannel", optionalStruct);
// dataChannel.onmessage = function(e){trace("DC message:" +e.data);};
// dataChannel.onopen = function(){trace("DC OPENED");dcOpen=true;};
// dataChannel.onclose = function(){trace("DC CLOSED");};
// dataChannel.onerror = function(){trace("DC ERROR");};
peerConnection.setRemoteDescription(/*try variations here*/ adata.data);
peerConnection.createAnswer(sdpConstraints).then(function (sdp) {
trace("Answer made.");
peerConnection.setLocalDescription(sdp);
sendNegotiation("answer", sdp);
});
}
if (adata.action=="answer") {
trace("Answer recieved.");
peerConnection.setRemoteDescription(/*try variations here*/ adata.data);
}
if (adata.action=="candidate") {
trace("ICE candidate recieved, looks like:",adata);
var soItDoesntComplain:Dynamic = adata.data;
peerConnection.addIceCandidate(soItDoesntComplain);
}
}
}
}
if (ready) {
trace("connected to net");
}
});
// notifyOnRemove(function() {
// });
}
}
You will notice a great deal of code is commented out -- I was expirementing with moving the dataChannel creation around.
For a better idea of what the issue is, here is the console output for the recieving and initiating clients, respectively:
In case you are wondering, notifyOnInit gets a function that is executed once at the beginning, and notifyOnUpdate gets a function called at a regular interval. object.properties['go'] is set by a different class when the username is given.
The JS api is basically the same (as far as I can tell, I haven't used WebRTC at all in the past), I haven't noticed any differences yet and I'm very sure that my issue is my fault and not Haxe's.
Thank you to those who answer.
this is not answer.
Anxious point.
peerCoonection.createOffer()
peerCoonection.createAnswer()
peerCoonection.setLocalDescription()
peerCoonection.setRemoteDescription()
peerCoonection.addIceCandidate()
are await is required.
top.js
const opts = require('minimist')(process.argv);
const failAfter = Number(opts['fail-after'] );
function importTest(name, path) {
describe(name, function() {
require(path);
});
}
describe('top', function() {
var fileMatches = null;
let failures = 0;
afterEach(function() {
console.log(this.currentTest.state);
if(this.currentTest.state == 'failed') {
console.log("fail-after = " +failAfter);
failures++;
console.log("failures = " +failures);
if(failures == failAfter){
console.log('\nToo many failures, exiting...');
process.exit(1);
}
}
});
importTest("a",'./test/a/a.js');
importTest("b",'./test/b/b.js');
importTest("test",'./test/test.js');
importTest("test1",'./test/test1.js');
});
I am trying to wrap all my mocha integration tests written in different files in my 'top' describe(written above). The purpose of this is to stop the tests after a particular number of test case failures(specified by the user in 'fail-after').
To include all the tests I have to explicitly call importTest() and pass the path of each test file. I want to automate it, so that I do not have to give the path of each file and instead all the files in the directory and sub-directories are covered.
Can someone suggest a way to do the same?
I run my tests using command "mocha --fail-after=5 ./top.js"
Solved the above problem by using the Glob npm module.
Solution:
top.js
const opts = require('minimist')(process.argv);
const failAfter = Number(opts['fail-after'] );
var Glob = require("glob");
var pattern = "*.js";
var options = {matchBase: true, nonull: true};
function importTest(name, path) {
describe(name, function() {
require(path);
});
}
describe('top', function () {
let failures = 0;
afterEach(function () {
console.log(this.currentTest.state);
if (this.currentTest.state == 'failed') {
failures++;
console.log("failures = " + failures);
if (failures == failAfter) {
console.log('\nToo many failures, exiting...');
process.exit(1);
}
}
});
function globArray(pattern, options) {
var list = [];
var pathList = Glob.sync(pattern, options);
pathList.forEach(function (item) {
list.push("./"+item);
});
return list;
}
var mg = globArray(pattern, options);
for(var i=0; i<mg.length; i++) {
importTest("sample", mg[i]);
}
});
I just started using Mocha. I'm writing a test that requires file cleanup, whether the test succeeds or not. Here's what I'm kind of looking for:
describe('example',function(){
fs.writeFile(file,'foo', function(){
it('should succeed', function(done){
done();
describe('example2', function(){
it('should do something awesome', function(done){
done();
});
})
}
}
});
});
});
afterAllTests(function(){
fs.unlink(file);
})
What I'm looking for is to delete all my created files during the test. Right now, I delete them after my last test completes. But if any test fails, the files don't get deleted. I did look into after(), but it only runs after my first test. The only other option that I can see is doing afterEvery(), and setting a variable like var testFinished = false; at the beginning and setting the value to true once completed. Is this the best way?
Thanks!
I wrote a file system wrapper that tracks the files written and can then delete all of them. Note: I only wrapped the functions I was using. You can easily add more.
// trackedfs.js
var fs = require('fs');
function deleteNoFail(filePath) {
if (filePath && fs.existsSync(filePath)) {
if (fs.lstatSync(filePath).isDirectory()) {
fs.rmdirSync(filePath);
} else {
fs.unlinkSync(filePath);
}
}
};
function makeTrackedFS(options) {
options = options || {};
var f = options.fs || fs;
var files = [];
var folders = [];
var links = [];
function addFile(file) {
files.push(file);
}
function addFolder(folder) {
folders.push(folder);
}
function addLink(link) {
links.push(link);
};
// Expose these in case we want to manually add stuff
// like if we shell out to another program we can add
// its output
f.addFile = addFile;
f.addFolder = addFolder;
f.addLink = addLink;
f.mkdirSync = function(origFn) {
return function() {
addFolder(arguments[0]);
return origFn.apply(f, arguments);
};
}(f.mkdirSync);
f.symlinkSync = function(origFn) {
return function() {
addLink(arguments[1]);
return origFn.apply(f, arguments);
};
}(f.symlinkSync);
f.writeFileSync = function(origFn) {
return function() {
addFile(arguments[0]);
return origFn.apply(f, arguments);
};
}(f.writeFileSync);
function deleteList(list) {
list.reverse(); // because we want files before dirs
list.forEach(function(entry) {
deleteNoFail(entry);
});
};
// call to delete everything
f.cleanup = function(options) {
deleteList(links);
deleteList(files);
deleteList(folders);
links = [];
files = [];
folders = [];
};
};
exports.makeTrackedFS = makeTrackedFS;
I can now wrap fs with
var trackedfs = require('trackedfs');
trackedfs.makeTrackedFS();
and set for cleanup with this
function cleanUpOnExit() {
fs.cleanup();
};
function cleanUpOnExitAndExit() {
cleanUpOnExit();
process.exit();
}
process.on('exit', cleanUpEncodersOnExit);
process.on('SIGINT', cleanUpEncodersOnExitAndExit);
process.on('uncaughtException', cleanUpEncodersOnExitAndExit);
Here's a test
var trackedfs = require('../lib/trackedfs');
var fs = require('fs');
trackedfs.makeTrackedFS();
function cleanUpOnExit() {
fs.cleanup();
};
function cleanUpOnExitAndExit() {
cleanUpOnExit();
process.exit();
}
process.on('exit', cleanUpOnExit);
process.on('SIGINT', cleanUpOnExitAndExit);
process.on('uncaughtException', cleanUpOnExitAndExit);
describe("trackedfs", function() {
it('makes a directory', function() {
fs.mkdirSync('foo');
});
it('writes a file', function() {
fs.writeFileSync("foo/bar", "hello");
});
});
Run it and there will be no foo folder or foo/bar file when done.
The one issue is that it probably can't delete files that are still opened so if you open a file and then crash your test it might not be able to delete it.
For some reason... when the page first loads $scope.$on('$cpuResult', cpuUpdate); doesn't catch the first broadcast. I verified that the first broadcast is going out successfully with console.log("broadcast");. The first broadcast is important to initialize the data, how come $scope.$on('$cpuResult', cpuUpdate); is not catching the first broadcast and how can I fix this?
angular.module('monitorApp')
.controller('cpuCtrl', function($scope) {
$scope.avaiable = "";
$scope.apiTimeStamp = "";
$scope.infoReceived = "";
$scope.last15 = "";
$scope.last5 = "";
$scope.lastMinute = "";
var cpuUpdate = function (e, result) {
console.log("yay");
$scope.$apply(function () {
$scope.available = result.cpuResult.avaiable;
$scope.apiTimeStamp = result.cpuResult.timestamp;
$scope.infoReceived = new Date();
$scope.last15 = result.cpuResult.metrics['15m'].data
$scope.last5 = result.cpuResult.metrics['5m'].data
$scope.lastMinute = result.cpuResult.metrics['1m'].data
});
}
$scope.$on('$cpuResult', cpuUpdate);
});
angular.module('monitorApp')
.run(function ($rootScope) {
var source = new EventSource('/subscribe');
source.addEventListener('message', function(e) {
var result = JSON.parse(e.data);
event = Object.keys(result)[0];
switch(event) {
case "cpuResult":
console.log("broadcast");
$rootScope.$broadcast('$cpuResult', result);
break;
}
});
});
<script src="scripts/angularApp.js"></script>
<script src="scripts/controllers/main.js"></script>
<script src="scripts/services/sse_listen.js"></script>
The controller isn't yet created by the time your first event is getting pushed out. You can refactor the app run into a factory that exposes the result data, and then watch the data from your controller:
angular.module('monitorApp').
factory('sseHandler', function ($timeout) {
var sseHandler = {};
sseHandler.result = {};
var source = new EventSource('/subscribe');
source.addEventListener('message', function(e) {
var result = JSON.parse(e.data);
event = Object.keys(result)[0];
switch(event) {
case "cpuResult":
console.log('sseHandler result change');
//The controller will watch the result
//on this object
$timeout(function(){
sseHandler.result = result;
});
//I wrap the result change in a timeout
//to schedule an apply,
//which will trigger your watches to run
//their dirty checks.
break;
}
});
return sseHandler; //return the object with exposed result
}).
controller('cpuCtrl', function($scope, sseHandler) {
$scope.avaiable = "";
$scope.apiTimeStamp = "";
$scope.infoReceived = "";
$scope.last15 = "";
$scope.last5 = "";
$scope.lastMinute = "";
var cpuUpdate = function (result) {
console.log("yay");
// You don't need the apply here anymore.
$scope.available = result.cpuResult.avaiable;
$scope.apiTimeStamp = result.cpuResult.timestamp;
$scope.infoReceived = new Date();
$scope.last15 = result.cpuResult.metrics['15m'].data;
$scope.last5 = result.cpuResult.metrics['5m'].data;
$scope.lastMinute = result.cpuResult.metrics['1m'].data;
}
// The second argument of the watch gets called when
// the result of the first argument changes
// I'm assuming timestamp changes often enough
$scope.$watch(function(){
return sseHandler.result.timestamp;
}, function(){
cpuUpdate(sseHandler.result);
});
});