Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

AnimateRunner adds to the $timeout queue when the document is hidden but does not flush the queue  #16048

Open

Description

I'm submitting a ...

  • bug report
  • feature request
  • other (Please do not submit support requests here (see above))

Current behavior:

AnimateRunner in https://github.com/angular/angular.js/blob/07849779ba365f371a8caa3b58e23f677cfdc5ad/src/ng/animateRunner.js runs timeoutTick (line 89) or rafTick (line 91), depending on whether or not the document is hidden. If the document is not hidden, rafTick will be executed and its queue will be flushed. However, in the case where the document is hidden, $timeout will be used and a pending task will be added to the $timeout queue. This pending task is never flushed which can lead to bugs when using $timeout.verifyNoPendingTasks in tests.

Expected / new behavior:

When the document is hidden (such as when using jsdom) the $timeout queue needs to be flushed.

Minimal reproduction of the problem with instructions:

https://plnkr.co/edit/617KlYg237TkWKDOtECG

We are using jest (and jsdom) for testing. Jsdom sets document.hidden to true for the duration of all tests (see 8.3.0 of https://github.com/tmpvar/jsdom/blob/master/Changelog.md). This plunker is a simple directive that will show or hide (using ng-if) based on a mouse event. I copied $$AnimateRunnerFactoryProvider from the source and used $provide.provider to overwrite the existing functionality. Since I can't import jsdom in plunker, I forced timeoutTick to be called instead of rafTick:

function AnimateRunner(host) {
            this.setHost(host);

            var rafTick = $$animateAsyncRun();
            var timeoutTick = function(fn) {
              $timeout(fn, 0, false);
            };

            this._doneCallbacks = [];
            this._tick = function(fn) {
              timeoutTick(fn);
              // if ($$isDocumentHidden()) {
              //   timeoutTick(fn);
              // } else {
              //   rafTick(fn);
              // }
            };
            this._state = 0;
          }

The test in the plunker shows that there is a pending entry in $timeout. We should not have to clear this pending entry in our tests.

Angular version: 1.x.y

The plunker is using angular@1.6.4.

Browser: [all | Chrome XX | Firefox XX | Edge XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]

This will occur if document.hidden is true. It is not browser specific.

Anything else:

The pending entry in the timeout needs to be cleared. We should be able to update $$AnimateRunnerFactory to do this similar to how the raf queue is being cleaned up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions