# test.web/core/observers/element.observer.test.ts

> 52 lines of code and 0 definitions.

Tree: Codebase Testing
Language: typescript
Canonical: https://banes-lab.com/anatomy/testing#file-testing-test-web-core-observers-element-observer-test-ts
Source text: https://banes-lab.com/source/testing/test.web/core/observers/element.observer.test.ts.txt

Listed in [test.web/core/observers](https://banes-lab.com/api/source/testing/test.web/core/observers.md), after [test.web/core/observers/document.observer.test.ts](https://banes-lab.com/source/testing/test.web/core/observers/document.observer.test.ts.md) and before [test.web/core/observers/route.observer.test.ts](https://banes-lab.com/source/testing/test.web/core/observers/route.observer.test.ts.md).

## Contained in

- [test.web/core/observers](https://banes-lab.com/anatomy/testing/folder-testing-test-web-core-observers.md)

## Source

```typescript
import { ANIMATE_ATTRIBUTE, FADE_IN } from "@banes-lab/web/configuration/constants/element.constants.ts";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createElement } from "@banes-lab/web/core/factories/element.factory.ts";
import { observeAnimations } from "@banes-lab/web/core/observers/element.observer.ts";

const ANIMATED_CLASS = "animated";
const TRIGGER_ATTRIBUTE = "data-animate-trigger";
const LOAD = "load";

const observed: Element[] = [];

class FakeIntersectionObserver {
    public observe(element: Element): void {
        observed.push(element);
    }

    public unobserve(): void {
        observed.length = 0;
    }

    public disconnect(): void {
        observed.length = 0;
    }
}

beforeEach(() => {
    observed.length = 0;
    vi.stubGlobal("IntersectionObserver", FakeIntersectionObserver);
});

afterEach(() => {
    vi.unstubAllGlobals();
});

describe("observeAnimations", () => {
    it("hands viewport-triggered elements to the intersection observer", () => {
        const target = createElement("div", { attributes: { [ANIMATE_ATTRIBUTE]: FADE_IN } });
        const root = createElement("div", { children: [target] });
        const dispose = observeAnimations(root);
        expect(observed).toContain(target);
        dispose();
    });

    it("animates load-triggered elements immediately", () => {
        const target = createElement("div", {
            attributes: { [ANIMATE_ATTRIBUTE]: FADE_IN, [TRIGGER_ATTRIBUTE]: LOAD },
        });
        const root = createElement("div", { children: [target] });
        const dispose = observeAnimations(root);
        expect(target.classList.contains(ANIMATED_CLASS)).toBe(true);
        expect(observed).not.toContain(target);
        dispose();
    });

    it("returns a disposer that stops observing", () => {
        const root = createElement("div");
        const dispose = observeAnimations(root);
        expect(() => {
            dispose();
        }).not.toThrow();
    });
});
```
