ember-test-helpers: visit() throws TransitionAborted error
As discussed in Slack, I was unexpectedly seeing failing tests where a transition was aborted.
ApplicationInstance#visit is throwing it here
As I said I cannot share the app, but this is the human readable test spec (we have a rather exotic test setup with ember-cli-yadda š):
Scenario: Access restricted page as invited user and login
Given there exists a user with username "testname" and password "testpw"
And I am an invited user
And I am on the homepage
When I go to the user profile page
Then I should still be on the homepage
And I should see the login modal
When I insert "testname" as the username
And I insert "testpw" as the password
And I submit the login form
Then I should be on the user profile page
The I go to the user profile page step is throwing the exception, which is calling visit('/user/profile') internally.
I quickly assembled this little repro, that resembles what we were doing in a very minimal way: https://github.com/simonihmig/ember-visit-transition-abort
All the acceptance tests are passing, with the exception of this last one: https://github.com/simonihmig/ember-visit-transition-abort/blob/master/tests/acceptance/auth-test.js#L36-L40
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 20
- Comments: 42 (9 by maintainers)
Commits related to this issue
- Convert automatic sign out test This also includes a new helper (credit to @ppcano here: https://github.com/emberjs/ember-test-helpers/issues/332#issuecomment-414641697) to work around https://github... — committed to travis-ci/travis-web by clekstro 5 years ago
- Convert automatic sign out test This also includes a new helper (credit to @ppcano here: https://github.com/emberjs/ember-test-helpers/issues/332#issuecomment-414641697) to work around https://github... — committed to travis-ci/travis-web by clekstro 5 years ago
- Convert more tests to modern testing style (#2054) * Convert broadcasts test to new style * Convert home/with-repositories to new testing style * Fix ESLint error * Convert another test ... — committed to travis-ci/travis-web by clekstro 5 years ago
- Add handling for invalid tokens Thanks to @ppcano for the visitWithAbortedTransition suggestion here: https://github.com/emberjs/ember-test-helpers/issues/332 — committed to backspace/waydowntown-app by backspace 5 years ago
- Handle api explorer routing error - For some reason when routing is done during async process, router transtionTo throws the TransitionAbortedError - As a fix treat this particular error as success s... — committed to hashicorp/vault by arnav28 3 years ago
- Handle api explorer routing error (#12354) * Handle api explorer routing error - For some reason when routing is done during async process, router transtionTo throws the TransitionAbortedError - ... — committed to hashicorp/vault by arnav28 3 years ago
- Handle api explorer routing error (#12354) * Handle api explorer routing error - For some reason when routing is done during async process, router transtionTo throws the TransitionAbortedError - ... — committed to hashicorp/vault by arnav28 3 years ago
- Handle api explorer routing error (#12354) * Handle api explorer routing error - For some reason when routing is done during async process, router transtionTo throws the TransitionAbortedError - ... — committed to hashicorp/vault by arnav28 3 years ago
- Handle api explorer routing error (#12354) (#12385) * Handle api explorer routing error - For some reason when routing is done during async process, router transtionTo throws the TransitionAborted... — committed to hashicorp/vault by arnav28 3 years ago
- Handle api explorer routing error (#12354) * Handle api explorer routing error - For some reason when routing is done during async process, router transtionTo throws the TransitionAbortedError - ... — committed to jartek/vault by arnav28 3 years ago
- Handle api explorer routing error (#12354) * Handle api explorer routing error - For some reason when routing is done during async process, router transtionTo throws the TransitionAbortedError - ... — committed to hashicorp/vault by arnav28 3 years ago
- Handle api explorer routing error (#12354) (#12555) * Handle api explorer routing error - For some reason when routing is done during async process, router transtionTo throws the TransitionAborted... — committed to hashicorp/vault by arnav28 3 years ago
- Fix followRedirects when source is async and destination is sync The previous implementation of `followRedirects()` would catch a transition rejection and check the router for an `activeTransition`. ... — committed to davidtaylorhq/router.js by davidtaylorhq 7 months ago
- Fix followRedirects when source is async and destination is sync The previous implementation of `followRedirects()` would catch a transition rejection and check the router for an `activeTransition`. ... — committed to davidtaylorhq/router.js by davidtaylorhq 7 months ago
- Better errors from visitable This adds the actual error message from Ember's router to the (too generic) message from `visitable`. This is especially important when your test needs to know what kind ... — committed to simonihmig/ember-cli-page-object by simonihmig 4 months ago
- Better errors from visitable (#640) * Better errors from visitable This adds the actual error message from Ember's router to the (too generic) message from `visitable`. This is especially importan... — committed to san650/ember-cli-page-object by simonihmig 4 months ago
Just to check in here, Iāve been trying to track down exactly what is going on and I think I have a fairly good picture. Essentially what is happening is that the secondary transition completes during the
beforeModel/model/afterModelof the first one, and since the full secondary transition has completed the routerās error handling throws this error instead of entangling the new transition with it like we do when there is an active transition.Ultimately, returning anything other than the actual resulting
Transitionobject will cause the error reported here to bubble up. This includes making any of thebeforeModel/model/afterModelmethods themselves async (because then you are returning aPromisenot aTransition), or returning anRSVP.Promisethat later resolves to aTransition(e.g.return this.store.findRecord('post', 1).then((record) => if (record.whatever) { return this.transitionTo(...); }).I know this is what folks were reporting all along, but now I actually understand it š©. Sorry for taking so long to dig in here. Iām trying to work up a solution using @sethphillipsās reproduction.
I am also experiencing this issue when migrating our test suite (
Ember 2.17&ember-cli-qunit ^4.1.1)We are using
transition.abortandtransition.retryto handle route authentication at the route level as suggested on the Preventing and Retrying Transitions guide.Based on @NullVoxPopuli guidance, our current workaround has been to implement a wrapper of the
visithelper:Minor addition to @ppcanoās solution as the original
settleis interrupted by the error.do we have a path forward? or a list of what this is waiting on?
do we have a resolution here?
having
visitthrow on transition isnāt good DX, imo.I know fixing it would have to be a breaking release⦠but⦠thatās fine? š
It looks like this issue extends beyond the
visit()helper. It affects any use oftransition.followRedirects()(which is essentially whatvisit()is doing).I have a failing test case and fix for router.js here: https://github.com/tildeio/router.js/pull/335
And then a tweak to Ember core so that it leans on
followRedirects()instead of reimplementing the same logic: https://github.com/emberjs/ember.js/pull/20574this Issue is mentioned in 20 different places in our code. with ToDos
@simonihmig āĀ weāve been running into this too. Just opened a PR with a failing test and a place to start: https://github.com/emberjs/ember-test-helpers/pull/373
(Iād be curious if it fixes your issue)
I discovered a new workaround after not being able to get the other workarounds mentioned above working in Ember 4.
Iām not entirely sure why this is working, but doing the transition within a function delayed via
setTimeoutfixes the error for me:I think this is because it moves the entire transition out of the promise chain, so the rejection is not captured by
ember-test-waiters. So this is still likely a hack and a workaround, rather than a permanent solution. But when I do this, theTransitionAbortedrejection no longer appears (nor the subsequenttestWaiter.endAsync called with no preceding testWaiter.beginAsync call.which appears in the console after theTransitionAbortedrejection).For context, the transition itself is happening within
ember-simple-auth, which Iāve overridden to make the hack work. Currently we have an authenticated route that looks like:The
requireAuthenticationeventually callstransitionTowhen the user is not logged in, which is what generates the error. To fix this, I overroderequireAuthenticationwithin the session service:This works because the second parameter of
requireAuthenticationcan be a route to redirect to or a callback to call when the user is not authenticated. We only ever pass a string route in, so wrapping it in a callback during testing to fix the error introduces minimal deviance from the production code.@rwjblue Hmm in my failing test the problem occurs even with a
returncould there be another problem that im not aware of?Im still having this issue, in my case this happens if i add a
asyncto mybeforeModelhook. After that, every test which renders this route throws aTransitionAborted.I have some
transitionTos happening in my afterModel hook ā which is intentional ā but in my testvisitis raising a TransitionAborted exception.The only way for my test to pass is:
I would love to have this update so we donāt have to define our own to workaround this.
Riffing on @NullVoxPopuli, how about an extra key for the
optionsthevisit(ā¦)method accepts? Something like{ silenceTransitionAborted: true }or something like that⦠My thinking is that aborted transitions would not be the default and, with this extra option, it becomes explicit that we expect it. Thoughts?@SebastianPetric I was able to workaround this issue by wrapping my
visitcalls in a try-catch block for tests that specifically intend to execute the aborted transition behavior. Itās not ideal, but it did temporarily unblock us.Weāre also banging our heads against this issue.
FWIW: The route seems to be loaded as expected after a non-async-
visit()-then-timeout. However any subsequentassert()never fires:This issue makes acceptance testing unusable for us for the time being. Iād love to find a workaround, or even better be pointed towards fixing any possible bad-practice that is causing this. Or trust @rwjblue to find a patch/solution, of course.
Thanks!
I solved it by adding the error hook and using that to transition instead. Might be sufficient for some people.
just upgraded from 3.5.1 to 3.18.0 and am seeing this on any routes that we redirect in async beforeModel. similar to others, Iām doing something like this.
async beforeModel(){ let name = await fetch('athing') this.registration.setHostApp(name); return this.replaceWith('intended-route'); }removing the async will remove the TransitionAborted error in tests.
@rwjblue We are running into this as well. The difference is that we are actually returning the abort. Any idea why this is still a problem based on the following code?
Previously user was a preset val, now itās a promise, so we have to await. Hence the reason we are ārunning into itā.
Because otherwise, the
beforeModelpromise resolves before thereplaceWithhas resolved. This is commonly referred to as āfloating promisesā (@typescript-eslint/no-floating-promises), and will result in theAbortTransitionrejection happening after the rest of the transition has moved further forward (and therefore will not be entangled with the router transition promise chain, which means the rejection happens out of band causing the reported error).