-
-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Testing a custom attributes' valueChanged() hook #70
Comments
@MarcScheib doing the assertion after a timeout might work as valueChanged callbacks are not called synchronously
|
Yes, that worked @suneelv . Thank you! |
This affect me as well, and the above work around does not resolve it. |
I've run into a similar problem countless times in my own tests:
The go-to workaround is to put step 2 inside a I'm getting very tired of it. I want to find a solution where the test will deterministically succeed. I've been trying to figure out where the delay occurs, but I can't figure it out. From my understanding, each model update should synchronously trigger Aurelia's property observer, which puts a microtask on the queue to update linked bindings. The microtask queue is flushed with a DOM mutation observer which is a JS microtask. So by the time the Could someone explain it to me, please? @EisenbergEffect perhaps, or @fkleuver? Is there any way for me to delay the DOM check in my test so that the binding update is guaranteed to have been resolved? |
Our solution has been to waitFor your assertion. // Rather than
expect(divEl.style.background).toEqual(newBg);
// waitFor instead, we have a helper function as the aurelia-testing is asserting against whether something is null rather than truthy/falsy
import { waitFor } from 'aurelia-testing';
export class WaitForBool {
static async truthy(callback) {
return await waitFor(() => callback() ? true : null);
}
static async falsy(callback) {
return await waitFor(() => callback() ? null : false);
}
}
// Then your actual assertion
await WaitForBool.truthy(() => divEl.style.background === newBg); |
@tomtomau Thanks for the suggestion. I'm already using that construct in some places. But we have tens of thousands of assertions in our tests, and I fear if we use |
@RomkeVdMeulen this is an issue with how our v1 setup the task queue. One trick that you can use to eliminate this problem forever is to reuse a single task queue instance in tests. There' many ways to do it, depends on your bootstrapping, one way is to wrap bootstrapper function with your one: import {bootstrap as $bootstrap} from 'aurelia-bootstrapper';
import { TaskQueue } from 'aurelia-task-queue';
let taskQueue: TaskQueue;
export function bootstrap(aurelia: Aurelia) {
if (taskQueue) {
aurelia.container.registerInstance(TaskQueue, taskQueue);
} else {
taskQueue = aurelia.container.get(TaskQueue);
}
return $bootstrap(aurelia);
} And later in your code, instead of taskQueue.flushMicroTaskQueue(); |
@bigopon Thanks for the tip! I'll try it out. |
Also does that mean this won't be an issue anymore in V2? |
Not at all, at least i believe so. For the above, make sure you flush all existing queues when disposing an app at the end of a test as well. |
@bigopon I tried your suggestion: I re-used one task queue throughout the test run, making sure to manually flush the micro queue before assertions and during tear down. It didn't seem to make a difference. I'm still seeing intermittent failures where the DOM wasn't updated in time for the assertion. I'm also trying to understand why flushing the queue manually should make a difference. Isn't the micro task queue always flushed before the start of the next event loop? (I run my tasks in Chrome, so MutationObservers are supported) |
I've been trying to create a minimal reproducable case, but so far without much luck. I've looked into all kinds of contributing factors, like async/await or computed properties, but as far as I can see none of those should be able to create a delay beyond the current event loop. Perhaps the issue isn't with timing, but with some state not being properly cleaned between test runs, like with issue #93. Because these errors are so infrequent, I'm having a devil of a time debugging them. |
It doesn't seem to be a case of stale view state. Let me give a simplified example of what I'm seeing:
And once in a dozen runs the output is:
Of course the real code has composition, more indirection, DI, computed properties, etc. but in essence this is what it boils down to. |
@RomkeVdMeulen here's a test that can be used to verify your repro. You can un-comment the method call in Edit: i gave you a wrong example code though, sorry! It should have been import { bootstrap as $bootstrap } from 'aurelia-bootstrapper';
let taskQueue;
export function bootstrap(configure) {
const $configure = aurelia => {
if (taskQueue) {
aurelia.container.registerInstance(TaskQueue, taskQueue);
} else {
taskQueue = aurelia.container.get(TaskQueue);
}
return configure(aurelia);
};
return $bootstrap($configure);
} |
@bigopon You're right, the repro works fine. I've been trying to narrow down where the delay is coming from, but as you can imagine with the delay only occuring randomly among lots of test runs it's very slow going. Thanks for your help. If I do find the problem I'll let you know. For now just consider this closed from my side. |
Hijacking this thread to improve my general knowledge with this tool. I was trying to verify that the click callback on a button was being called. My initial implementation was with
That didn't trigger the click handler (called with With the help of this comment #70 (comment) I realised I could use the My question is, why is the classic DOM Event method not being a trigger? Is this a preferred approach for any event or would there be cases where Thanks |
@lemoustachiste there shouldn't be any issue with what you are trying to do. Can you help give a repro of what you want to do, based on the example here https://gist.dumber.app/?gist=650aecc59a32d08776692a4b5055b7c0 |
I'm submitting a bug report
^1.0.0-beta.3.0.1
Please tell us about your environment:
Operating System:
Windows 10
Node Version:
8.1.3
NPM Version:
5.0.3
JSPM OR Webpack AND Version
JSPM 0.16.53
Browser:
Chrome
Language:
ESNext
Current behavior:
When testing a custom attribute with one bound value and
valueChanged()
method, the method is not called during the spec, although the value binding is working in e.g. an input field.The
valueChanged()
is called during testing when changing the bound value.Testing the logic of a custom attributes
valueChanged()
hook.I am using the following code so far and binding is also working for the input, but not for the custom attribute:
The text was updated successfully, but these errors were encountered: