Add personal notes, DeepSearch history, backup offload, and gateway auth throttling
DevPlace CI / test (push) Failing after 28m20s
DevPlace CI / test (push) Failing after 28m20s
Also streamline the top navigation: drop the Tools dropdown, make Quizzes and Battles icon-only entries, and remove the Workspace, Containers and Editor entry points from the project detail page.
This commit is contained in:
@@ -406,3 +406,120 @@ def test_live_incoming_message_shows_report_button(alice, bob):
|
||||
bubble = page_b.locator(f".message-bubble.theirs:has-text('{msg}')")
|
||||
bubble.wait_for(state="visible", timeout=10000)
|
||||
expect(bubble.locator(".message-report-btn")).to_be_visible()
|
||||
|
||||
|
||||
def test_send_button_locks_during_send_and_prevents_duplicate(alice, bob):
|
||||
page_a, user_a = alice
|
||||
page_b, user_b = bob
|
||||
uid_b = get_table("users").find_one(username=user_b["username"])["uid"]
|
||||
|
||||
page_a.goto(
|
||||
f"{BASE_URL}/messages?with_uid={uid_b}", wait_until="domcontentloaded"
|
||||
)
|
||||
|
||||
msg = f"Locked send {int(time.time() * 1000)}"
|
||||
textarea = page_a.locator(".messages-input-area textarea[name='content']")
|
||||
textarea.wait_for(state="visible")
|
||||
textarea.fill(msg)
|
||||
|
||||
send_btn = page_a.locator(".messages-send-btn")
|
||||
send_btn.click()
|
||||
|
||||
# the composer refuses a duplicate submit while this send is unconfirmed
|
||||
expect(send_btn).to_be_disabled()
|
||||
|
||||
bubble = page_a.locator(f".message-bubble.mine:has-text('{msg}')")
|
||||
reconciled = page_a.locator(
|
||||
f".message-bubble.mine:has-text('{msg}')[data-msg-uid]:not(.pending)"
|
||||
)
|
||||
reconciled.first.wait_for(state="visible", timeout=10000)
|
||||
|
||||
expect(send_btn).to_be_enabled()
|
||||
assert bubble.count() == 1
|
||||
|
||||
|
||||
def test_scroll_up_is_not_yanked_by_incoming_message(alice, bob):
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from devplacepy.utils import generate_uid
|
||||
|
||||
page_a, user_a = alice
|
||||
page_b, user_b = bob
|
||||
uid_a = get_table("users").find_one(username=user_a["username"])["uid"]
|
||||
uid_b = get_table("users").find_one(username=user_b["username"])["uid"]
|
||||
|
||||
base = datetime.now(timezone.utc) - timedelta(minutes=5)
|
||||
for i in range(40):
|
||||
get_table("messages").insert(
|
||||
{
|
||||
"uid": generate_uid(),
|
||||
"sender_uid": uid_a if i % 2 == 0 else uid_b,
|
||||
"receiver_uid": uid_b if i % 2 == 0 else uid_a,
|
||||
"content": f"scroll history line {i}",
|
||||
"read": True,
|
||||
"created_at": (base + timedelta(seconds=i)).isoformat(),
|
||||
"updated_at": None,
|
||||
}
|
||||
)
|
||||
|
||||
page_a.goto(
|
||||
f"{BASE_URL}/messages?with_uid={uid_b}", wait_until="domcontentloaded"
|
||||
)
|
||||
page_b.goto(
|
||||
f"{BASE_URL}/messages?with_uid={uid_a}", wait_until="domcontentloaded"
|
||||
)
|
||||
|
||||
thread = page_a.locator(".messages-thread")
|
||||
thread.wait_for(state="visible")
|
||||
thread.locator(".message-bubble").first.wait_for(state="visible")
|
||||
|
||||
thread.evaluate(
|
||||
"el => { el.scrollTop = 0; el.dispatchEvent(new Event('scroll')); }"
|
||||
)
|
||||
page_a.wait_for_timeout(200)
|
||||
scroll_before = thread.evaluate("el => el.scrollTop")
|
||||
assert scroll_before < 50
|
||||
|
||||
msg = f"While scrolled up {int(time.time() * 1000)}"
|
||||
textarea_b = page_b.locator(".messages-input-area textarea[name='content']")
|
||||
textarea_b.wait_for(state="visible")
|
||||
textarea_b.fill(msg)
|
||||
page_b.locator(".messages-send-btn").click()
|
||||
|
||||
page_a.locator(f".message-bubble.theirs:has-text('{msg}')").first.wait_for(
|
||||
state="visible", timeout=10000
|
||||
)
|
||||
scroll_after = thread.evaluate("el => el.scrollTop")
|
||||
assert scroll_after < 50, (
|
||||
"an incoming message must not yank a scrolled-up reader back to the bottom"
|
||||
)
|
||||
|
||||
|
||||
def test_scroll_stays_pinned_to_bottom_for_active_reader(alice, bob):
|
||||
page_a, user_a = alice
|
||||
page_b, user_b = bob
|
||||
uid_a = get_table("users").find_one(username=user_a["username"])["uid"]
|
||||
uid_b = get_table("users").find_one(username=user_b["username"])["uid"]
|
||||
|
||||
page_a.goto(
|
||||
f"{BASE_URL}/messages?with_uid={uid_b}", wait_until="domcontentloaded"
|
||||
)
|
||||
page_b.goto(
|
||||
f"{BASE_URL}/messages?with_uid={uid_a}", wait_until="domcontentloaded"
|
||||
)
|
||||
|
||||
thread = page_a.locator(".messages-thread")
|
||||
thread.wait_for(state="visible")
|
||||
|
||||
msg = f"Pinned bottom {int(time.time() * 1000)}"
|
||||
textarea_b = page_b.locator(".messages-input-area textarea[name='content']")
|
||||
textarea_b.wait_for(state="visible")
|
||||
textarea_b.fill(msg)
|
||||
page_b.locator(".messages-send-btn").click()
|
||||
|
||||
page_a.locator(f".message-bubble.theirs:has-text('{msg}')").first.wait_for(
|
||||
state="visible", timeout=10000
|
||||
)
|
||||
at_bottom = thread.evaluate(
|
||||
"el => el.scrollHeight - el.scrollTop - el.clientHeight < 100"
|
||||
)
|
||||
assert at_bottom, "an active-at-bottom reader must still auto-scroll to new messages"
|
||||
|
||||
Reference in New Issue
Block a user