2023-08-25 11:54:23 +00:00
|
|
|
from django.urls import reverse
|
|
|
|
from playwright.sync_api import sync_playwright, expect
|
|
|
|
|
|
|
|
from bookmarks.e2e.helpers import LinkdingE2ETestCase
|
|
|
|
from bookmarks.models import Bookmark
|
|
|
|
|
|
|
|
|
|
|
|
class BookmarkPagePartialUpdatesE2ETestCase(LinkdingE2ETestCase):
|
|
|
|
def setup_test_data(self):
|
|
|
|
self.setup_numbered_bookmarks(50)
|
|
|
|
self.setup_numbered_bookmarks(50, archived=True)
|
2024-01-27 10:29:16 +00:00
|
|
|
self.setup_numbered_bookmarks(50, prefix="foo")
|
|
|
|
self.setup_numbered_bookmarks(50, archived=True, prefix="foo")
|
|
|
|
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(
|
|
|
|
is_archived=False, title__startswith="Bookmark"
|
|
|
|
).count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(
|
|
|
|
is_archived=True, title__startswith="Archived Bookmark"
|
|
|
|
).count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(is_archived=False, title__startswith="foo").count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(is_archived=True, title__startswith="foo").count(),
|
|
|
|
)
|
2023-08-25 11:54:23 +00:00
|
|
|
|
|
|
|
def test_active_bookmarks_bulk_select_across(self):
|
|
|
|
self.setup_test_data()
|
|
|
|
|
|
|
|
with sync_playwright() as p:
|
2024-01-27 10:29:16 +00:00
|
|
|
self.open(reverse("bookmarks:index"), p)
|
2023-08-25 11:54:23 +00:00
|
|
|
|
2024-03-24 21:07:11 +00:00
|
|
|
bookmark_list = self.locate_bookmark_list()
|
2023-08-25 11:54:23 +00:00
|
|
|
self.locate_bulk_edit_toggle().click()
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
self.locate_bulk_edit_select_across().click()
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
self.select_bulk_action("Delete")
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Execute").click()
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Confirm").click()
|
2024-03-24 21:07:11 +00:00
|
|
|
# Wait until bookmark list is updated (old reference becomes invisible)
|
|
|
|
expect(bookmark_list).not_to_be_visible()
|
2024-01-27 10:29:16 +00:00
|
|
|
|
|
|
|
self.assertEqual(
|
|
|
|
0,
|
|
|
|
Bookmark.objects.filter(
|
|
|
|
is_archived=False, title__startswith="Bookmark"
|
|
|
|
).count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(
|
|
|
|
is_archived=True, title__startswith="Archived Bookmark"
|
|
|
|
).count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
0,
|
|
|
|
Bookmark.objects.filter(is_archived=False, title__startswith="foo").count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(is_archived=True, title__startswith="foo").count(),
|
|
|
|
)
|
2023-08-25 11:54:23 +00:00
|
|
|
|
|
|
|
def test_archived_bookmarks_bulk_select_across(self):
|
|
|
|
self.setup_test_data()
|
|
|
|
|
|
|
|
with sync_playwright() as p:
|
2024-01-27 10:29:16 +00:00
|
|
|
self.open(reverse("bookmarks:archived"), p)
|
2023-08-25 11:54:23 +00:00
|
|
|
|
2024-03-24 21:07:11 +00:00
|
|
|
bookmark_list = self.locate_bookmark_list()
|
2023-08-25 11:54:23 +00:00
|
|
|
self.locate_bulk_edit_toggle().click()
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
self.locate_bulk_edit_select_across().click()
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
self.select_bulk_action("Delete")
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Execute").click()
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Confirm").click()
|
2024-03-24 21:07:11 +00:00
|
|
|
# Wait until bookmark list is updated (old reference becomes invisible)
|
|
|
|
expect(bookmark_list).not_to_be_visible()
|
2024-01-27 10:29:16 +00:00
|
|
|
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(
|
|
|
|
is_archived=False, title__startswith="Bookmark"
|
|
|
|
).count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
0,
|
|
|
|
Bookmark.objects.filter(
|
|
|
|
is_archived=True, title__startswith="Archived Bookmark"
|
|
|
|
).count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(is_archived=False, title__startswith="foo").count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
0,
|
|
|
|
Bookmark.objects.filter(is_archived=True, title__startswith="foo").count(),
|
|
|
|
)
|
2023-08-25 11:54:23 +00:00
|
|
|
|
|
|
|
def test_active_bookmarks_bulk_select_across_respects_query(self):
|
|
|
|
self.setup_test_data()
|
|
|
|
|
|
|
|
with sync_playwright() as p:
|
2024-01-27 10:29:16 +00:00
|
|
|
self.open(reverse("bookmarks:index") + "?q=foo", p)
|
2023-08-25 11:54:23 +00:00
|
|
|
|
2024-03-24 21:07:11 +00:00
|
|
|
bookmark_list = self.locate_bookmark_list()
|
2023-08-25 11:54:23 +00:00
|
|
|
self.locate_bulk_edit_toggle().click()
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
self.locate_bulk_edit_select_across().click()
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
self.select_bulk_action("Delete")
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Execute").click()
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Confirm").click()
|
2024-03-24 21:07:11 +00:00
|
|
|
# Wait until bookmark list is updated (old reference becomes invisible)
|
|
|
|
expect(bookmark_list).not_to_be_visible()
|
2024-01-27 10:29:16 +00:00
|
|
|
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(
|
|
|
|
is_archived=False, title__startswith="Bookmark"
|
|
|
|
).count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(
|
|
|
|
is_archived=True, title__startswith="Archived Bookmark"
|
|
|
|
).count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
0,
|
|
|
|
Bookmark.objects.filter(is_archived=False, title__startswith="foo").count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(is_archived=True, title__startswith="foo").count(),
|
|
|
|
)
|
2023-08-25 11:54:23 +00:00
|
|
|
|
|
|
|
def test_archived_bookmarks_bulk_select_across_respects_query(self):
|
|
|
|
self.setup_test_data()
|
|
|
|
|
|
|
|
with sync_playwright() as p:
|
2024-01-27 10:29:16 +00:00
|
|
|
self.open(reverse("bookmarks:archived") + "?q=foo", p)
|
2023-08-25 11:54:23 +00:00
|
|
|
|
2024-03-24 21:07:11 +00:00
|
|
|
bookmark_list = self.locate_bookmark_list()
|
2023-08-25 11:54:23 +00:00
|
|
|
self.locate_bulk_edit_toggle().click()
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
self.locate_bulk_edit_select_across().click()
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
self.select_bulk_action("Delete")
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Execute").click()
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Confirm").click()
|
2024-03-24 21:07:11 +00:00
|
|
|
# Wait until bookmark list is updated (old reference becomes invisible)
|
|
|
|
expect(bookmark_list).not_to_be_visible()
|
2024-01-27 10:29:16 +00:00
|
|
|
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(
|
|
|
|
is_archived=False, title__startswith="Bookmark"
|
|
|
|
).count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(
|
|
|
|
is_archived=True, title__startswith="Archived Bookmark"
|
|
|
|
).count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
50,
|
|
|
|
Bookmark.objects.filter(is_archived=False, title__startswith="foo").count(),
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
0,
|
|
|
|
Bookmark.objects.filter(is_archived=True, title__startswith="foo").count(),
|
|
|
|
)
|
2023-08-25 11:54:23 +00:00
|
|
|
|
|
|
|
def test_select_all_toggles_all_checkboxes(self):
|
|
|
|
self.setup_numbered_bookmarks(5)
|
|
|
|
|
|
|
|
with sync_playwright() as p:
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:index")
|
2023-08-25 11:54:23 +00:00
|
|
|
page = self.open(url, p)
|
|
|
|
|
|
|
|
self.locate_bulk_edit_toggle().click()
|
|
|
|
|
2024-04-11 17:07:20 +00:00
|
|
|
checkboxes = page.locator("label.bulk-edit-checkbox input")
|
2023-08-25 11:54:23 +00:00
|
|
|
self.assertEqual(6, checkboxes.count())
|
|
|
|
for i in range(checkboxes.count()):
|
|
|
|
expect(checkboxes.nth(i)).not_to_be_checked()
|
|
|
|
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
|
|
|
|
for i in range(checkboxes.count()):
|
|
|
|
expect(checkboxes.nth(i)).to_be_checked()
|
|
|
|
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
|
|
|
|
for i in range(checkboxes.count()):
|
|
|
|
expect(checkboxes.nth(i)).not_to_be_checked()
|
|
|
|
|
|
|
|
def test_select_all_shows_select_across(self):
|
|
|
|
self.setup_numbered_bookmarks(5)
|
|
|
|
|
|
|
|
with sync_playwright() as p:
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:index")
|
2023-08-25 11:54:23 +00:00
|
|
|
self.open(url, p)
|
|
|
|
|
|
|
|
self.locate_bulk_edit_toggle().click()
|
|
|
|
|
|
|
|
expect(self.locate_bulk_edit_select_across()).not_to_be_visible()
|
|
|
|
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
expect(self.locate_bulk_edit_select_across()).to_be_visible()
|
|
|
|
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
expect(self.locate_bulk_edit_select_across()).not_to_be_visible()
|
|
|
|
|
|
|
|
def test_select_across_is_unchecked_when_toggling_all(self):
|
|
|
|
self.setup_numbered_bookmarks(5)
|
|
|
|
|
|
|
|
with sync_playwright() as p:
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:index")
|
2023-08-25 11:54:23 +00:00
|
|
|
self.open(url, p)
|
|
|
|
|
|
|
|
self.locate_bulk_edit_toggle().click()
|
|
|
|
|
|
|
|
# Show select across, check it
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
self.locate_bulk_edit_select_across().click()
|
|
|
|
expect(self.locate_bulk_edit_select_across()).to_be_checked()
|
|
|
|
|
|
|
|
# Hide select across by toggling select all
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
expect(self.locate_bulk_edit_select_across()).not_to_be_visible()
|
|
|
|
|
|
|
|
# Show select across again, verify it is unchecked
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
expect(self.locate_bulk_edit_select_across()).not_to_be_checked()
|
|
|
|
|
|
|
|
def test_select_across_is_unchecked_when_toggling_bookmark(self):
|
|
|
|
self.setup_numbered_bookmarks(5)
|
|
|
|
|
|
|
|
with sync_playwright() as p:
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:index")
|
2023-08-25 11:54:23 +00:00
|
|
|
self.open(url, p)
|
|
|
|
|
|
|
|
self.locate_bulk_edit_toggle().click()
|
|
|
|
|
|
|
|
# Show select across, check it
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
self.locate_bulk_edit_select_across().click()
|
|
|
|
expect(self.locate_bulk_edit_select_across()).to_be_checked()
|
|
|
|
|
|
|
|
# Hide select across by toggling a single bookmark
|
2024-01-27 10:29:16 +00:00
|
|
|
self.locate_bookmark("Bookmark 1").locator(
|
2024-04-11 17:07:20 +00:00
|
|
|
"label.bulk-edit-checkbox"
|
2024-01-27 10:29:16 +00:00
|
|
|
).click()
|
2023-08-25 11:54:23 +00:00
|
|
|
expect(self.locate_bulk_edit_select_across()).not_to_be_visible()
|
|
|
|
|
|
|
|
# Show select across again, verify it is unchecked
|
2024-01-27 10:29:16 +00:00
|
|
|
self.locate_bookmark("Bookmark 1").locator(
|
2024-04-11 17:07:20 +00:00
|
|
|
"label.bulk-edit-checkbox"
|
2024-01-27 10:29:16 +00:00
|
|
|
).click()
|
2023-08-25 11:54:23 +00:00
|
|
|
expect(self.locate_bulk_edit_select_across()).not_to_be_checked()
|
|
|
|
|
|
|
|
def test_execute_resets_all_checkboxes(self):
|
|
|
|
self.setup_numbered_bookmarks(100)
|
|
|
|
|
|
|
|
with sync_playwright() as p:
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:index")
|
2023-08-25 11:54:23 +00:00
|
|
|
page = self.open(url, p)
|
|
|
|
|
2024-03-24 21:07:11 +00:00
|
|
|
bookmark_list = self.locate_bookmark_list()
|
|
|
|
|
2023-08-25 11:54:23 +00:00
|
|
|
# Select all bookmarks, enable select across
|
|
|
|
self.locate_bulk_edit_toggle().click()
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
self.locate_bulk_edit_select_across().click()
|
|
|
|
|
|
|
|
# Execute bulk action
|
2024-01-27 10:29:16 +00:00
|
|
|
self.select_bulk_action("Mark as unread")
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Execute").click()
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Confirm").click()
|
2023-08-25 11:54:23 +00:00
|
|
|
|
|
|
|
# Wait until bookmark list is updated (old reference becomes invisible)
|
|
|
|
expect(bookmark_list).not_to_be_visible()
|
|
|
|
|
|
|
|
# Verify bulk edit checkboxes are reset
|
2024-04-11 17:07:20 +00:00
|
|
|
checkboxes = page.locator("label.bulk-edit-checkbox input")
|
2023-08-25 11:54:23 +00:00
|
|
|
self.assertEqual(31, checkboxes.count())
|
|
|
|
for i in range(checkboxes.count()):
|
|
|
|
expect(checkboxes.nth(i)).not_to_be_checked()
|
|
|
|
|
|
|
|
# Toggle select all and verify select across is reset
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
expect(self.locate_bulk_edit_select_across()).not_to_be_checked()
|
|
|
|
|
|
|
|
def test_update_select_across_bookmark_count(self):
|
|
|
|
self.setup_numbered_bookmarks(100)
|
|
|
|
|
|
|
|
with sync_playwright() as p:
|
2024-01-27 10:29:16 +00:00
|
|
|
url = reverse("bookmarks:index")
|
2023-08-25 11:54:23 +00:00
|
|
|
self.open(url, p)
|
|
|
|
|
2024-03-24 21:07:11 +00:00
|
|
|
bookmark_list = self.locate_bookmark_list()
|
2023-08-25 11:54:23 +00:00
|
|
|
self.locate_bulk_edit_toggle().click()
|
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
expect(
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("All pages (100 bookmarks)")
|
|
|
|
).to_be_visible()
|
2023-08-25 11:54:23 +00:00
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
self.select_bulk_action("Delete")
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Execute").click()
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("Confirm").click()
|
2024-03-24 21:07:11 +00:00
|
|
|
# Wait until bookmark list is updated (old reference becomes invisible)
|
|
|
|
expect(bookmark_list).not_to_be_visible()
|
2023-08-25 11:54:23 +00:00
|
|
|
|
2024-03-16 14:35:22 +00:00
|
|
|
expect(self.locate_bulk_edit_select_all()).not_to_be_checked()
|
2023-08-25 11:54:23 +00:00
|
|
|
self.locate_bulk_edit_select_all().click()
|
|
|
|
|
2024-01-27 10:29:16 +00:00
|
|
|
expect(
|
|
|
|
self.locate_bulk_edit_bar().get_by_text("All pages (70 bookmarks)")
|
|
|
|
).to_be_visible()
|