Files
upstream-zulip/web/tests/sidebar_header_sticky_shadow.test.cjs
upstream-mirror 64898b2c79
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
2026-09-15 15:05:30 +05:00

112 lines
3.8 KiB
JavaScript

"use strict";
const assert = require("node:assert/strict");
const {zrequire} = require("./lib/namespace.cjs");
const {run_test} = require("./lib/test.cjs");
const sidebar_header_sticky_shadow = zrequire("sidebar_header_sticky_shadow");
function make_header(top) {
const classes = new Set();
return {
getBoundingClientRect: () => ({top}),
classList: {
toggle(name, on) {
if (on) {
classes.add(name);
} else {
classes.delete(name);
}
},
has: (name) => classes.has(name),
},
};
}
function make_scroll_container({scrollTop, container_top, headers}) {
let scroll_listener;
const container = {
scrollTop,
getBoundingClientRect: () => ({top: container_top}),
querySelectorAll: () => headers,
addEventListener(event, callback, options) {
assert.equal(event, "scroll");
assert.deepEqual(options, {passive: true});
scroll_listener = callback;
},
};
return {
$wrapper: {length: 1, 0: container},
get scroll_listener() {
return scroll_listener;
},
container,
};
}
run_test("install toggles shadow based on stickiness", ({override}) => {
override(globalThis, "getComputedStyle", () => ({top: "40px"}));
// Container has been scrolled; pin line is at container_top + sticky_top = 50.
// Header sitting exactly at the pin line: stuck, shadow on.
const stuck_header = make_header(50);
// Header that has been pushed above the pin line by the next section
// arriving from below; shadow suppressed to avoid a visible seam at
// the junction.
const pushed_out_header = make_header(45);
// Header still below the pin line, not yet stuck.
const below_pin_line_header = make_header(500);
const scroll = make_scroll_container({
scrollTop: 120,
container_top: 10,
headers: [stuck_header, pushed_out_header, below_pin_line_header],
});
sidebar_header_sticky_shadow.initialize(scroll.$wrapper, ".header");
assert.ok(stuck_header.classList.has("sidebar-header-drop-shadow"));
assert.ok(!pushed_out_header.classList.has("sidebar-header-drop-shadow"));
assert.ok(!below_pin_line_header.classList.has("sidebar-header-drop-shadow"));
// The scroll listener re-runs the update logic.
assert.ok(typeof scroll.scroll_listener === "function");
scroll.scroll_listener();
assert.ok(stuck_header.classList.has("sidebar-header-drop-shadow"));
});
run_test("install leaves shadow off before any scroll", ({override}) => {
override(globalThis, "getComputedStyle", () => ({top: "40px"}));
// Same geometry as the stuck case above (header top=50, pin line=50),
// but scrollTop=0. Pre-set the shadow class so we can see install()
// actively removes it, proving the has_scrolled guard is doing its job.
const header = make_header(50);
header.classList.toggle("sidebar-header-drop-shadow", true);
const scroll = make_scroll_container({
scrollTop: 0,
container_top: 10,
headers: [header],
});
sidebar_header_sticky_shadow.initialize(scroll.$wrapper, ".header");
assert.ok(!header.classList.has("sidebar-header-drop-shadow"));
});
run_test("install handles missing computed top", ({override}) => {
override(globalThis, "getComputedStyle", () => ({top: "auto"}));
// With sticky_top defaulting to 0, a header at container_top is stuck.
const container_top = 10;
const header = make_header(container_top);
const scroll = make_scroll_container({
scrollTop: 50,
container_top,
headers: [header],
});
sidebar_header_sticky_shadow.initialize(scroll.$wrapper, ".header");
assert.ok(header.classList.has("sidebar-header-drop-shadow"));
});