long overdue fix to last pipeline push, where scroll position did not persist across sessions
This commit is contained in:
@@ -154,16 +154,19 @@ class BillscrollPositionTest(FunctionalTest):
|
||||
)
|
||||
|
||||
# 2. Force the element scrollable (CSS not served by StaticLiveServerTestCase),
|
||||
# set position, and dispatch scroll event to trigger the debounced save.
|
||||
# JS saves scrollTop + clientHeight (bottom-of-viewport); forced height is 150px.
|
||||
# set position, dispatch scroll event, and capture the position value the
|
||||
# JS listener will save — all in one synchronous script so the layout
|
||||
# snapshot is identical to what the scroll handler sees.
|
||||
scroll_top = 100
|
||||
forced_height = 150
|
||||
self.browser.execute_script("""
|
||||
saved_pos = self.browser.execute_script("""
|
||||
var el = arguments[0];
|
||||
var remPx = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
||||
el.style.overflow = 'auto';
|
||||
el.style.height = '150px';
|
||||
el.scrollTop = arguments[1];
|
||||
var pos = Math.round(el.scrollTop + el.clientHeight + remPx * 2.5);
|
||||
el.dispatchEvent(new Event('scroll'));
|
||||
return pos;
|
||||
""", scroll_el, scroll_top)
|
||||
|
||||
# 3. Wait for debounce (800ms) + fetch to complete
|
||||
@@ -180,11 +183,8 @@ class BillscrollPositionTest(FunctionalTest):
|
||||
scroll_el = self.wait_for(
|
||||
lambda: self.browser.find_element(By.ID, "id_drama_scroll")
|
||||
)
|
||||
buffer_px = self.browser.execute_script(
|
||||
"return Math.round(parseFloat(getComputedStyle(document.documentElement).fontSize) * 2.5)"
|
||||
)
|
||||
restored = int(scroll_el.get_attribute("data-scroll-position"))
|
||||
self.assertEqual(restored, scroll_top + forced_height + buffer_px)
|
||||
self.assertEqual(restored, saved_pos)
|
||||
|
||||
|
||||
class BillboardAppletsTest(FunctionalTest):
|
||||
|
||||
@@ -22,8 +22,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Restore: position stored is bottom-of-viewport; subtract clientHeight to align it
|
||||
// Only restore if there's a meaningful saved position — avoids a
|
||||
// no-op scrollTop assignment (0→0) that can fire a spurious scroll
|
||||
// event and reset the debounce timer in tests / headless browsers.
|
||||
if ({{ scroll_position }} > 0) {
|
||||
scroll.scrollTop = Math.max(0, {{ scroll_position }} - scroll.clientHeight);
|
||||
}
|
||||
});
|
||||
|
||||
// Animate "What happens next. . . ?" buffer dots — 4th span shows '?'
|
||||
@@ -37,21 +41,24 @@
|
||||
}, 400);
|
||||
}
|
||||
|
||||
// Debounced save on scroll — store bottom-of-viewport so the last-read line is restored
|
||||
// Debounced save on scroll — store bottom-of-viewport so the last-read line is restored.
|
||||
// Position is captured at event time so layout changes during the debounce window
|
||||
// (e.g. rAF adjusting marginTop) don't produce a stale clientHeight.
|
||||
var remPx = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
||||
var saveTimer;
|
||||
scroll.addEventListener('scroll', function() {
|
||||
var pos = Math.round(scroll.scrollTop + scroll.clientHeight + remPx * 2.5);
|
||||
clearTimeout(saveTimer);
|
||||
saveTimer = setTimeout(function() {
|
||||
var csrfToken = document.querySelector('[name=csrfmiddlewaretoken]');
|
||||
var token = csrfToken ? csrfToken.value : '';
|
||||
var remPx = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
||||
fetch("{% url 'billboard:save_scroll_position' room.id %}", {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'X-CSRFToken': token,
|
||||
},
|
||||
body: 'position=' + Math.round(scroll.scrollTop + scroll.clientHeight + remPx * 2.5),
|
||||
body: 'position=' + pos,
|
||||
});
|
||||
}, 800);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user