snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
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
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
This commit is contained in:
111
web/tests/sidebar_header_sticky_shadow.test.cjs
Normal file
111
web/tests/sidebar_header_sticky_shadow.test.cjs
Normal file
@@ -0,0 +1,111 @@
|
||||
"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"));
|
||||
});
|
||||
Reference in New Issue
Block a user