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) 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()) def test_active_bookmarks_bulk_select_across(self): self.setup_test_data() with sync_playwright() as p: self.open(reverse('bookmarks:index'), p) self.locate_bulk_edit_toggle().click() self.locate_bulk_edit_select_all().click() self.locate_bulk_edit_select_across().click() 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() 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()) def test_archived_bookmarks_bulk_select_across(self): self.setup_test_data() with sync_playwright() as p: self.open(reverse('bookmarks:archived'), p) self.locate_bulk_edit_toggle().click() self.locate_bulk_edit_select_all().click() self.locate_bulk_edit_select_across().click() 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() 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()) def test_active_bookmarks_bulk_select_across_respects_query(self): self.setup_test_data() with sync_playwright() as p: self.open(reverse('bookmarks:index') + '?q=foo', p) self.locate_bulk_edit_toggle().click() self.locate_bulk_edit_select_all().click() self.locate_bulk_edit_select_across().click() 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() 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()) def test_archived_bookmarks_bulk_select_across_respects_query(self): self.setup_test_data() with sync_playwright() as p: self.open(reverse('bookmarks:archived') + '?q=foo', p) self.locate_bulk_edit_toggle().click() self.locate_bulk_edit_select_all().click() self.locate_bulk_edit_select_across().click() 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() 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()) def test_select_all_toggles_all_checkboxes(self): self.setup_numbered_bookmarks(5) with sync_playwright() as p: url = reverse('bookmarks:index') page = self.open(url, p) self.locate_bulk_edit_toggle().click() checkboxes = page.locator('label[ld-bulk-edit-checkbox] input') 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: url = reverse('bookmarks:index') 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: url = reverse('bookmarks:index') 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: url = reverse('bookmarks:index') 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 self.locate_bookmark('Bookmark 1').locator('label[ld-bulk-edit-checkbox]').click() expect(self.locate_bulk_edit_select_across()).not_to_be_visible() # Show select across again, verify it is unchecked self.locate_bookmark('Bookmark 1').locator('label[ld-bulk-edit-checkbox]').click() 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: url = reverse('bookmarks:index') page = self.open(url, p) # 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() # Get reference for bookmark list bookmark_list = page.locator('ul[ld-bookmark-list]') # Execute bulk action 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() # Wait until bookmark list is updated (old reference becomes invisible) expect(bookmark_list).not_to_be_visible() # Verify bulk edit checkboxes are reset checkboxes = page.locator('label[ld-bulk-edit-checkbox] input') 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: url = reverse('bookmarks:index') self.open(url, p) self.locate_bulk_edit_toggle().click() self.locate_bulk_edit_select_all().click() expect(self.locate_bulk_edit_bar().get_by_text('All pages (100 bookmarks)')).to_be_visible() 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() self.locate_bulk_edit_select_all().click() expect(self.locate_bulk_edit_bar().get_by_text('All pages (70 bookmarks)')).to_be_visible()