feat: Add non-color indicator to vote button state #168
@@ -340,6 +340,14 @@ def assert_share_copies(page, expected_fragment):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def vote_glyph(locator):
|
||||||
|
value = locator.evaluate("el => getComputedStyle(el, '::before').content")
|
||||||
|
value = value.strip().strip('"').strip("'")
|
||||||
|
if value.startswith("\\") and len(value) == 5 and value[1:].isdigit():
|
||||||
|
value = chr(int(value[1:], 16))
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
def assert_no_horizontal_overflow(page, layout):
|
def assert_no_horizontal_overflow(page, layout):
|
||||||
report = page.evaluate(
|
report = page.evaluate(
|
||||||
"""(selector) => {
|
"""(selector) => {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ def test_leaderboard_ranks_after_upvote(app_server, browser, seeded_db):
|
|||||||
|
|
||||||
pa.goto(post_url, wait_until="domcontentloaded")
|
pa.goto(post_url, wait_until="domcontentloaded")
|
||||||
pa.wait_for_timeout(1000)
|
pa.wait_for_timeout(1000)
|
||||||
vote_btn = pa.locator("button.post-action-btn").filter(has_text="+").first
|
vote_btn = pa.locator("button.post-action-btn.vote-up").first
|
||||||
vote_btn.wait_for(state="visible", timeout=10000)
|
vote_btn.wait_for(state="visible", timeout=10000)
|
||||||
vote_btn.click()
|
vote_btn.click()
|
||||||
pa.wait_for_timeout(1500)
|
pa.wait_for_timeout(1500)
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ def test_vote_notification_on_post(app_server, browser, seeded_db):
|
|||||||
|
|
||||||
pa.goto(post_url, wait_until="domcontentloaded")
|
pa.goto(post_url, wait_until="domcontentloaded")
|
||||||
pa.wait_for_timeout(1000)
|
pa.wait_for_timeout(1000)
|
||||||
vote_btn = pa.locator("button.post-action-btn").filter(has_text="+").first
|
vote_btn = pa.locator("button.post-action-btn.vote-up").first
|
||||||
vote_btn.wait_for(state="visible", timeout=10000)
|
vote_btn.wait_for(state="visible", timeout=10000)
|
||||||
vote_btn.click()
|
vote_btn.click()
|
||||||
pa.wait_for_timeout(1500)
|
pa.wait_for_timeout(1500)
|
||||||
@@ -796,7 +796,7 @@ def test_vote_notification_click_opens_target(app_server, browser, seeded_db):
|
|||||||
|
|
||||||
pa.goto(f"{BASE_URL}{post_path}", wait_until="domcontentloaded")
|
pa.goto(f"{BASE_URL}{post_path}", wait_until="domcontentloaded")
|
||||||
pa.wait_for_timeout(1000)
|
pa.wait_for_timeout(1000)
|
||||||
vote_btn = pa.locator("button.post-action-btn").filter(has_text="+").first
|
vote_btn = pa.locator("button.post-action-btn.vote-up").first
|
||||||
vote_btn.wait_for(state="visible", timeout=10000)
|
vote_btn.wait_for(state="visible", timeout=10000)
|
||||||
vote_btn.click()
|
vote_btn.click()
|
||||||
pa.wait_for_timeout(1500)
|
pa.wait_for_timeout(1500)
|
||||||
|
|||||||
+52
-22
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
from playwright.sync_api import expect
|
from playwright.sync_api import expect
|
||||||
from tests.conftest import BASE_URL, assert_share_copies
|
from tests.conftest import BASE_URL, assert_share_copies, vote_glyph
|
||||||
def create_post(page, topic="random", content="Test post content", title=None):
|
def create_post(page, topic="random", content="Test post content", title=None):
|
||||||
page.goto(f"{BASE_URL}/feed", wait_until="domcontentloaded")
|
page.goto(f"{BASE_URL}/feed", wait_until="domcontentloaded")
|
||||||
page.locator(".feed-fab").first.wait_for(state="visible", timeout=10000)
|
page.locator(".feed-fab").first.wait_for(state="visible", timeout=10000)
|
||||||
@@ -74,35 +74,57 @@ def test_post_vote_increment(alice):
|
|||||||
def test_post_upvote_voted_state_persists(alice):
|
def test_post_upvote_voted_state_persists(alice):
|
||||||
page, _ = alice
|
page, _ = alice
|
||||||
create_post(page, "showcase", "Upvote persistence test")
|
create_post(page, "showcase", "Upvote persistence test")
|
||||||
|
vote_up = page.locator(".post-action-btn.vote-up").first
|
||||||
|
assert vote_glyph(vote_up) == "+"
|
||||||
with page.expect_response(
|
with page.expect_response(
|
||||||
lambda r: "/votes/" in r.url and r.request.method == "POST"
|
lambda r: "/votes/" in r.url and r.request.method == "POST"
|
||||||
):
|
):
|
||||||
page.locator(".post-action-btn.vote-up").first.click()
|
vote_up.click()
|
||||||
expect(page.locator(".post-vote-count").first).to_have_text("1")
|
expect(page.locator(".post-vote-count").first).to_have_text("1")
|
||||||
|
expect(vote_up).to_have_class(re.compile(r"\bvoted\b"))
|
||||||
|
assert vote_glyph(vote_up) == "\u2295"
|
||||||
page.reload(wait_until="domcontentloaded")
|
page.reload(wait_until="domcontentloaded")
|
||||||
expect(page.locator(".post-action-btn.vote-up").first).to_have_class(
|
vote_up = page.locator(".post-action-btn.vote-up").first
|
||||||
re.compile(r"\bvoted\b")
|
expect(vote_up).to_have_class(re.compile(r"\bvoted\b"))
|
||||||
)
|
assert vote_glyph(vote_up) == "\u2295"
|
||||||
assert "voted" not in (
|
vote_down = page.locator(".post-action-btn.vote-down").first
|
||||||
page.locator(".post-action-btn.vote-down").first.get_attribute("class") or ""
|
assert "voted" not in (vote_down.get_attribute("class") or "")
|
||||||
)
|
assert vote_glyph(vote_down) == "\u2212"
|
||||||
|
with page.expect_response(
|
||||||
|
lambda r: "/votes/" in r.url and r.request.method == "POST"
|
||||||
|
):
|
||||||
|
vote_up.click()
|
||||||
|
expect(page.locator(".post-vote-count").first).to_have_text("0")
|
||||||
|
expect(vote_up).not_to_have_class(re.compile(r"\bvoted\b"))
|
||||||
|
assert vote_glyph(vote_up) == "+"
|
||||||
|
|
||||||
|
|
||||||
def test_post_downvote_voted_state_persists(alice):
|
def test_post_downvote_voted_state_persists(alice):
|
||||||
page, _ = alice
|
page, _ = alice
|
||||||
create_post(page, "showcase", "Downvote persistence test")
|
create_post(page, "showcase", "Downvote persistence test")
|
||||||
|
vote_down = page.locator(".post-action-btn.vote-down").first
|
||||||
|
assert vote_glyph(vote_down) == "\u2212"
|
||||||
with page.expect_response(
|
with page.expect_response(
|
||||||
lambda r: "/votes/" in r.url and r.request.method == "POST"
|
lambda r: "/votes/" in r.url and r.request.method == "POST"
|
||||||
):
|
):
|
||||||
page.locator(".post-action-btn.vote-down").first.click()
|
vote_down.click()
|
||||||
expect(page.locator(".post-vote-count").first).to_have_text("-1")
|
expect(page.locator(".post-vote-count").first).to_have_text("-1")
|
||||||
|
expect(vote_down).to_have_class(re.compile(r"\bvoted\b"))
|
||||||
|
assert vote_glyph(vote_down) == "\u2296"
|
||||||
page.reload(wait_until="domcontentloaded")
|
page.reload(wait_until="domcontentloaded")
|
||||||
expect(page.locator(".post-action-btn.vote-down").first).to_have_class(
|
vote_down = page.locator(".post-action-btn.vote-down").first
|
||||||
re.compile(r"\bvoted\b")
|
expect(vote_down).to_have_class(re.compile(r"\bvoted\b"))
|
||||||
)
|
assert vote_glyph(vote_down) == "\u2296"
|
||||||
assert "voted" not in (
|
vote_up = page.locator(".post-action-btn.vote-up").first
|
||||||
page.locator(".post-action-btn.vote-up").first.get_attribute("class") or ""
|
assert "voted" not in (vote_up.get_attribute("class") or "")
|
||||||
)
|
assert vote_glyph(vote_up) == "+"
|
||||||
|
with page.expect_response(
|
||||||
|
lambda r: "/votes/" in r.url and r.request.method == "POST"
|
||||||
|
):
|
||||||
|
vote_down.click()
|
||||||
|
expect(page.locator(".post-vote-count").first).to_have_text("0")
|
||||||
|
expect(vote_down).not_to_have_class(re.compile(r"\bvoted\b"))
|
||||||
|
assert vote_glyph(vote_down) == "\u2212"
|
||||||
|
|
||||||
|
|
||||||
def test_comment_voted_state_persists(alice):
|
def test_comment_voted_state_persists(alice):
|
||||||
@@ -114,17 +136,25 @@ def test_comment_voted_state_persists(alice):
|
|||||||
expect(
|
expect(
|
||||||
page.locator(".comment-text:has-text('Comment whose vote should persist')")
|
page.locator(".comment-text:has-text('Comment whose vote should persist')")
|
||||||
).to_be_visible()
|
).to_be_visible()
|
||||||
|
comment_vote = page.locator(".comment-vote-btn.vote-up").first
|
||||||
|
assert vote_glyph(comment_vote) == "+"
|
||||||
with page.expect_response(
|
with page.expect_response(
|
||||||
lambda r: "/votes/" in r.url and r.request.method == "POST"
|
lambda r: "/votes/" in r.url and r.request.method == "POST"
|
||||||
):
|
):
|
||||||
page.locator(".comment-vote-btn").first.click()
|
comment_vote.click()
|
||||||
expect(page.locator(".comment-vote-btn").first).to_have_class(
|
expect(comment_vote).to_have_class(re.compile(r"\bvoted\b"))
|
||||||
re.compile(r"\bvoted\b")
|
assert vote_glyph(comment_vote) == "\u2295"
|
||||||
)
|
|
||||||
page.reload(wait_until="domcontentloaded")
|
page.reload(wait_until="domcontentloaded")
|
||||||
expect(page.locator(".comment-vote-btn").first).to_have_class(
|
comment_vote = page.locator(".comment-vote-btn.vote-up").first
|
||||||
re.compile(r"\bvoted\b")
|
expect(comment_vote).to_have_class(re.compile(r"\bvoted\b"))
|
||||||
)
|
assert vote_glyph(comment_vote) == "\u2295"
|
||||||
|
with page.expect_response(
|
||||||
|
lambda r: "/votes/" in r.url and r.request.method == "POST"
|
||||||
|
):
|
||||||
|
comment_vote.click()
|
||||||
|
expect(page.locator(".comment-vote-count").first).to_have_text("0")
|
||||||
|
expect(comment_vote).not_to_have_class(re.compile(r"\bvoted\b"))
|
||||||
|
assert vote_glyph(comment_vote) == "+"
|
||||||
|
|
||||||
|
|
||||||
def test_mention_first_match_highlighted(alice):
|
def test_mention_first_match_highlighted(alice):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ def _create_plain_post_engagement_ui(page, content):
|
|||||||
page.wait_for_url(f"{BASE_URL}/posts/*", wait_until="domcontentloaded")
|
page.wait_for_url(f"{BASE_URL}/posts/*", wait_until="domcontentloaded")
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
from tests.conftest import BASE_URL, assert_share_copies
|
from tests.conftest import BASE_URL, assert_share_copies, vote_glyph
|
||||||
from devplacepy.database import get_table
|
from devplacepy.database import get_table
|
||||||
from devplacepy.utils import make_combined_slug
|
from devplacepy.utils import make_combined_slug
|
||||||
def _seed_posts(count):
|
def _seed_posts(count):
|
||||||
@@ -404,15 +404,19 @@ def test_feed_vote_voted_state_persists(alice):
|
|||||||
card = page.locator(
|
card = page.locator(
|
||||||
".post-card", has_text="Feed vote persistence test content"
|
".post-card", has_text="Feed vote persistence test content"
|
||||||
).first
|
).first
|
||||||
card.locator(".post-action-btn.vote-up").click()
|
vote_up = card.locator(".post-action-btn.vote-up")
|
||||||
|
assert vote_glyph(vote_up) == "+"
|
||||||
|
vote_up.click()
|
||||||
expect(card.locator(".post-vote-count")).to_have_text("1")
|
expect(card.locator(".post-vote-count")).to_have_text("1")
|
||||||
|
expect(vote_up).to_have_class(re.compile(r"\bvoted\b"))
|
||||||
|
assert vote_glyph(vote_up) == "\u2295"
|
||||||
page.goto(f"{BASE_URL}/feed", wait_until="domcontentloaded")
|
page.goto(f"{BASE_URL}/feed", wait_until="domcontentloaded")
|
||||||
card = page.locator(
|
card = page.locator(
|
||||||
".post-card", has_text="Feed vote persistence test content"
|
".post-card", has_text="Feed vote persistence test content"
|
||||||
).first
|
).first
|
||||||
expect(card.locator(".post-action-btn.vote-up")).to_have_class(
|
vote_up = card.locator(".post-action-btn.vote-up")
|
||||||
re.compile(r"\bvoted\b")
|
expect(vote_up).to_have_class(re.compile(r"\bvoted\b"))
|
||||||
)
|
assert vote_glyph(vote_up) == "\u2295"
|
||||||
|
|
||||||
|
|
||||||
def test_feed_card_share_button(alice):
|
def test_feed_card_share_button(alice):
|
||||||
|
|||||||
Reference in New Issue
Block a user