diff --git a/aio/content/examples/testing/src/app/shared/canvas.component.spec.ts b/aio/content/examples/testing/src/app/shared/canvas.component.spec.ts
new file mode 100644
index 0000000000..eacb67eb82
--- /dev/null
+++ b/aio/content/examples/testing/src/app/shared/canvas.component.spec.ts
@@ -0,0 +1,27 @@
+import { TestBed, async, tick, fakeAsync } from '@angular/core/testing';
+import { CanvasComponent } from './canvas.component';
+describe('CanvasComponent', () => {
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [
+ CanvasComponent
+ ],
+ }).compileComponents();
+ }));
+ beforeEach(() => {
+ window['__zone_symbol__FakeAsyncTestMacroTask'] = [
+ {
+ source: 'HTMLCanvasElement.toBlob',
+ callbackArgs: [{ size: 200 }]
+ }
+ ];
+ });
+ it('should be able to generate blob data from canvas', fakeAsync(() => {
+ const fixture = TestBed.createComponent(CanvasComponent);
+ fixture.detectChanges();
+ tick();
+ const app = fixture.debugElement.componentInstance;
+ expect(app.blobSize).toBeGreaterThan(0);
+ }));
+});
+
diff --git a/aio/content/examples/testing/src/app/shared/canvas.component.ts b/aio/content/examples/testing/src/app/shared/canvas.component.ts
new file mode 100644
index 0000000000..0f32dbeeb6
--- /dev/null
+++ b/aio/content/examples/testing/src/app/shared/canvas.component.ts
@@ -0,0 +1,25 @@
+import { Component, AfterViewInit, ViewChild } from '@angular/core';
+
+@Component({
+ selector: 'sample-canvas',
+ template: ''
+})
+export class CanvasComponent implements AfterViewInit {
+ blobSize: number;
+ @ViewChild('sampleCanvas') sampleCanvas;
+
+ constructor() { }
+
+ ngAfterViewInit() {
+ const canvas = this.sampleCanvas.nativeElement;
+ const context = canvas.getContext('2d');
+ if (context) {
+ context.clearRect(0, 0, 200, 200);
+ context.fillStyle = '#FF1122';
+ context.fillRect(0, 0, 200, 200);
+ canvas.toBlob((blob: any) => {
+ this.blobSize = blob.size;
+ });
+ }
+ }
+}
diff --git a/aio/content/guide/testing.md b/aio/content/guide/testing.md
index 3b556ad2a7..a7518dcc3a 100644
--- a/aio/content/guide/testing.md
+++ b/aio/content/guide/testing.md
@@ -1081,6 +1081,54 @@ In this case, it waits for the error handler's `setTimeout()`;
The `tick` function is one of the Angular testing utilities that you import with `TestBed`.
It's a companion to `fakeAsync` and you can only call it within a `fakeAsync` body.
+#### Support more macroTasks
+
+By default `fakeAsync` supports the following `macroTasks`.
+
+- setTimeout
+- setInterval
+- requestAnimationFrame
+- webkitRequestAnimationFrame
+- mozRequestAnimationFrame
+
+If you run other `macroTask` such as `HTMLCanvasElement.toBlob()`, `Unknown macroTask scheduled in fake async test` error will be thrown.
+
+
+
+
+
+
+
+
+If you want to support such case, you need to define the `macroTask` you want to support in `beforeEach`.
+For example:
+
+```javascript
+beforeEach(() => {
+ window['__zone_symbol__FakeAsyncTestMacroTask'] = [
+ {
+ source: 'HTMLCanvasElement.toBlob',
+ callbackArgs: [{ size: 200 }]
+ }
+ ];
+});
+
+it('toBlob should be able to run in fakeAsync', fakeAsync(() => {
+ const canvas: HTMLCanvasElement = document.getElementById('canvas') as HTMLCanvasElement;
+ let blob = null;
+ canvas.toBlob(function(b) {
+ blob = b;
+ });
+ tick();
+ expect(blob.size).toBe(200);
+ })
+);
+```
+
#### Async observables
You might be satisfied with the test coverage of these tests.
diff --git a/packages/core/testing/src/fake_async_fallback.ts b/packages/core/testing/src/fake_async_fallback.ts
index 7971726465..9e4c2aa028 100644
--- a/packages/core/testing/src/fake_async_fallback.ts
+++ b/packages/core/testing/src/fake_async_fallback.ts
@@ -143,7 +143,6 @@ export function flushFallback(maxTurns?: number): number {
*/
export function discardPeriodicTasksFallback(): void {
const zoneSpec = _getFakeAsyncZoneSpec();
- const pendingTimers = zoneSpec.pendingPeriodicTimers;
zoneSpec.pendingPeriodicTimers.length = 0;
}