For some reason, my code is unable to retrieve the IAsyncOperation object that is returned upon calling captureFileAsync method of the Windows.Media.Capture.CameraCaptureUI() method. The IAsyncOperation object is returned according to this documentation. In that documentation link, it states:
Return value
Type: IAsyncOperation<StorageFile>
When this operationcompletes, a StorageFile object is returned.
So here is my code:
var dialog = new Windows.Media.Capture.CameraCaptureUI();
var aspectRatio = { width: 4, height: 3 };
dialog.photoSettings.croppedAspectRatio = aspectRatio;
appSession.InAsyncMode = dialog.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.photo).done(function (file) {
if (file) {
self.addPage(URL.createObjectURL(file));
} else {
WinJS.log && WinJS.log("No photo captured.", "sample", "status");
}
}, function (err) {
// None taken
});
When I inspect the value of appSession.InAysncMode, I see that the function returns undefined. I suspect it returns undefined because the operation is not complete (i.e. the user has not yet created the photo, and it has not been saved to disc), but I need it in order to cancel out of the camera capture mode programmatically. Does anybody know why it would return undefined instead of the documented IAsyncOperation object?
Thanks!
For reference, here's the answer I posted on the MSDN forum.
To answer your ending question, you can cancel the capture UI by canceling the promise from dialog.captureFileAsync.
Your InAsyncMode flag is undefined because you're assigning to it the return value from captureFileAsync.done() which is, by definition, undefined. It has nothing to do with the API's success.
In the docs, when you see IAsyncOperation, what you get in JavaScript is a promise that will deliver as a result to the completed handler if it succeed. You never see IAsyncOperation or related interfaces in JavaScript directly. The documentation for WinRT is written to be language-neutral, so it's important to understand how those things show up in JS (as promises). In C# you don't see it either, as you just use the await keyword. It's mostly in C++ that you actually encounter the interface.
Anyway, you I believe you want is something along the lines of the code below, where you could eliminate IsAsyncMode in favor of just checking for a non-null promise:
appSession.capturePromise = dialog.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.photo);
appSession.IsAsyncMode = (appSession.capturePromise != null);
//This will close the capture UI after 5 seconds--replace with whatever logic you need
setTimeout(function () { appSession.capturePromise.cancel(); }, 5000);
appSession.capturePromise.done(function (file) {
if (file) {
} else {
}
}, function (err) {
appSession.IsAsyncMode = false;
appSession.capturePromise = null;
});
Related
I am looking for a way to overwrite expect method for TestController. My idea is existing tests whoever used t.expect method, I want to perform additional steps in those cases.
I came up with below sample code but testcafe runtime fails with below error
TypeError: Cannot read property '_expect$' of undefined
sample code attempting to override:
import { Selector } from "testcafe";
fixture`Getting Started`.page`http://devexpress.github.io/testcafe/example`;
test("My first test", async (t) => {
t = modify(t);
await t.typeText("#developer-name", "John Smith").click("#submit-button");
// Use the assertion to check if the actual header text is equal to the expected one
await t
.expect(Selector("#article-header").innerText)
.eql("Thank you, John Smith!");
});
function modify(t) {
let prevExpect = t.expect;
t.expect = (param) => {
console.log("modified expecte has been used");
return prevExpect(param);
};
return t;
}
Also, when using t.click(Selector(...).expect(...), It doesn't use my overwritten expect. How to make it work in the call chain as well?
Technically, it's possible to overwrite the expect method, but please note that this approach may lead to incorrect work and unexpected errors.
You need to modify your modify function as follows:
function modify (t) {
let prevExpect = t.expect;
t.expect = (param) => {
console.log("modified expect has been used");
return prevExpect.call(t, param);
};
return t;
}
As for the t.click(Selector(...).expect(...) issue, you call the expect method of Selector, but Selector does not have the expect method.
You need to add ) after Selector:
await t.click(Selector(...)).expect(...)
I have a simple call to Firestore to write a doc and then wait for the doc to finish writing before changing state of the parent. However, the parent state is being changed too fast, resulting in reading fields that I think have not yet been written/propagated. I tried adding a delay with setTimeout and it seems ignored. How can I make sure the state change is absolutely only called after the Firestore doc is written completely?
The code:
updateDBEntry(stateObj) {
var that = this;
var docRef = firebase.firestore().collection('sessions').doc(this.state.userID);
docRef.get().then((doc) => {
if (!doc.exists) {
const timestamp = firebase.firestore.FieldValue.serverTimestamp();
var duration = (stateObj.seshDuration) ? stateObj.seshDuration : 1;
docRef.set({
seshName: stateObj.seshName,
seshStreet: stateObj.seshStreet,
seshZipcode: stateObj.seshZipcode,
seshDuration: duration,
seshDesc: stateObj.seshDesc,
seshTime: timestamp,
}).then(() => {
var handleToUpdate = that.props.handleToUpdate;
setTimeout(() => {
handleToUpdate(1); //this changes the parent's state
}, 10000);
});
}
});
}
I'm not sure exactly the problem you're running into here, mostly because you've only shown this one function, and not how you're using it in the rest of your app. But I can tell you three things for sure:
When the promise from set() resolves successfully, you can be certain the document is written.
get() and set() are asynchronous, and so is then(). They all return promises the represent async work.
Item 2 means that your entire function updateDBEntry() is also asynchronous and returns immediately, before any of the work is complete.
Because this entire function is async, when it returns, the document will not have been created yet. Instead, maybe this function should return that resolves only after all the work is complete, so that the caller can also use it set up some code to execute after the work is done.
My CasperJS asserts seem to be overly strict. I have a function where I am trying to test the names of client logo images from an array, using Casperjs. However I do not seem to be able to use a variable from a forLoop in casperJS.
I understand there are probably hoisting issues that I am not accounting for, but this does not seem to be the primary problem. I have tried several things to resolve hoisting issues, such as immediately invoked functions, try catch blocks, and using ES6 term "Let" in my loop. None seem to work. Then I notice if I simply hard-code the string my variable should represent, and stick a console.log into my assert of a PASSING test, right before the return, the passing test fails.
Here is my failing code
var clients = 'https://www.google.com/';
var logoArray = ["images/logos/AC.png", "images/logos/Affiny.png", "images/logos/ffintus.png", "images/logos/agileAsset.png"]
function checkClientsArrayTest() {
casper.test.begin('The layout is as expected', 10, function suite(test) {
casper.start(clients, function () {
casper.then(function () {
for (var i = 0; i < logoArray.length; i++) {
try { throw i }
catch (ii) {
console.log(ii);
console.log(i);
test.assertEvalEquals(function () {
return document.querySelectorAll('div.client_logo a img')[ii].getAttribute('src')
.match(logoArray[ii]).toString();
}, logoArray[ii], 'Test searches for Client Logos in DOM.');
}
}
});
}).run(function () {
test.done();
});
});
}
If I change logoArray[ii] to a hardcoded string from the first index of the array, it passes. If I consolelog logoArray[ii], it seems to be what I expect. But if I pass a variable to the assert, or even stick a console.log inside of it, the test fails with the following
Running check for the layout of URL: https://www.google.com
0
0
FAIL Test searches for Client Logos in DOM.
type: assertEvalEquals
file: headlessTester.js
subject: null
fn: undefined
params: undefined
expected: "images/logos/AC.png"
Is this an issue of me getting hoisting wrong (shouldn't fail by sticking in a logger if this is the case afaik), or is this due to strictly structured asserts in CasperJS?
I'm trying to understand an article here, and now everything is clear but one code fragment, mentioned on pre-last code block, with a total of 1 to 17 lines, and this fragment is from line 1 to 9:
app.use(function(req,res,next) {
redis.get(req.user.email, function(err, id) {
if (err) next(err);
req.emitToUser = function() {
var soc = id && io.to(id);
soc.emit.apply(soc, arguments);
}
});
});
and I think its some shortcomings in my javascript knowledge are the root cause.
My knowledge over this code fragment:
The 'apply' method will execute the 'emit' with 'soc' as 'this' value
and feeds the 'emit' method with 'arguments' (am I right here
please?)
socket.id is related to the email of socket owner, because id.to(id) is based on the fact that the socket.id is the room where every socket is joined with itself. Redis provides the key-value data structure that holds user email as key, and the value is the socket.id.
problems:
where 'arguments' is coming from?
what's the purpose of this code fragment?
Please make me clear.
There are some issues with this code, but the general idea is to define a method on the req object req.emitToUser() for every incoming request that will allow some other route handler later in the chain to use that method to emit to the user who make the request. This is a common desire to want to connect a currently connected socket.io connection to the user making the http request.
Let's look at each line here:
redis.get(req.user.email, function(err, id) {
Look up the req.user.email in the redis database to get a socket.io id associated with that email that has previously been saved in that redis database.
if (err) next(err);
If it wasn't found in redis, make this request fail with an error.
req.emitToUser = function() {
Assign a new method to the current req object so that other route handlers later in the chain can use that method.
var soc = id && io.to(id);
Look up the id value in socket.io to get the socket for that id. Technically io.to() doesn't return the socket, but it returns an object that you can call emit() on that will send to that socket.
soc.emit.apply(soc, arguments);
The role of soc.emit.apply(soc, arguments); is this:
Execute the soc.emit() method
Set the this value when executing that method to the soc object.
Set the arguments when executing that method to whatever the arguments were that were passed to req.emitToUser(x, y, z) when it was called.
Here's a more concrete example:
function fn(a, b, c) {
console.log(a, b, c);
}
fn.apply(null, [1, 2, 3]);
Using fn.apply(null, [1, 2, 3]); will be the same as:
fn(1, 2, 3);
Now, you'd likely never use .apply() in this exact way when the arguments are already known. The case for using it is when you have some arbitrary array that is passed to you (you don't know what's in it) and you want to pass those arguments along to some other function in the exact same order as they were given to you. That's what soc.emit.apply(soc, arguments); is doing. It's taking the arguments object (which is an array-like structure that represents the arguments that were passed to the parent function req.emitToUser() and passing those exact arguments on it sock.emit(). If you knew exactly how many arguments there would be, then you could hard-code that same code as this:
app.use(function(req,res,next) {
redis.get(req.user.email, function(err, id) {
if (err) next(err);
req.emitToUser = function(msg, data) {
var soc = id && io.to(id);
soc.emit(msg, data);
}
});
});
But, .apply() creates a more generic solution that will work regardless of how many arguments were passed to req.emitToUser() as it will just pass all the arguments on to soc.emit().
This line of code is a bit suspect:
var soc = id && io.to(id);
It appears to be trying to protect against there not being a proper id returned from redis earlier. But, if there's no id, then soc will not be a valid object and the following like of code:
soc.emit.apply(soc, arguments);
will throw. So, the id && io.to(id) isn't really providing the proper protection. It appears this should more likely be:
app.use(function(req,res,next) {
redis.get(req.user.email, function(err, id) {
if (err) next(err);
req.emitToUser = function() {
if (id) {
var soc = io.to(id);
soc.emit.apply(soc, arguments);
} else {
// not sure what you want here, perhaps return an error
// or throw a more meaningful exception
}
}
});
});
What is the difference between returning an action vs returning the whole function in Page Object?
this.download = function() {
element(by.id('modal-download-button')).click();
return this;
};
VS
this.download = function() {
return element(by.id('modal-download-button')).click();
};
Sometimes, to tackle timing and syncing issues, you want to explicitly resolve a promise returned by click(). In this case returning the "click" promise makes sense:
pageObject.download().then(function () {
// ...
});
Returning a full page object could be useful for chaining page object methods:
pageObject.download().get().verify();