implementing favorite apps feature (#1410)
This PR implements favorite apps feature and addresses issue #827 <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Adds a favorite apps feature with a star toggle in the sidebar. Favorites are grouped separately and persisted, with optimistic UI updates and e2e tests. - **New Features** - Added isFavorite to the apps schema and an IPC handler (add-to-favorite) to toggle and persist the state. - Updated AppList to show “Favorite apps” and “Other apps” sections. - Introduced AppItem component with a star button; uses useAddAppToFavorite for optimistic updates and toasts. - Added Playwright tests to verify favoriting and unfavoriting. - **Migration** - Run DB migrations to add the apps.is_favorite column (defaults to 0). <!-- End of auto-generated description by cubic. -->
This commit is contained in:
committed by
GitHub
parent
e8b93e3298
commit
423a95ed81
72
e2e-tests/favorite_app.spec.ts
Normal file
72
e2e-tests/favorite_app.spec.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { test } from "./helpers/test_helper";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
test.describe("Favorite App Tests", () => {
|
||||
test("Add app to favorite", async ({ po }) => {
|
||||
await po.setUp({ autoApprove: true });
|
||||
|
||||
// Create a test app
|
||||
await po.sendPrompt("create a test app");
|
||||
await po.goToAppsTab();
|
||||
|
||||
// Get the app name from the UI (randomly generated)
|
||||
const appItems = await po.page.getByTestId(/^app-list-item-/).all();
|
||||
expect(appItems.length).toBeGreaterThan(0);
|
||||
const firstAppItem = appItems[0];
|
||||
const testId = await firstAppItem.getAttribute("data-testid");
|
||||
const appName = testId!.replace("app-list-item-", "");
|
||||
|
||||
// Get the app item (assuming it's not favorited initially)
|
||||
const appItem = po.page.locator(`[data-testid="app-list-item-${appName}"]`);
|
||||
await expect(appItem).toBeVisible();
|
||||
|
||||
// Click the favorite button
|
||||
const favoriteButton = appItem
|
||||
.locator("xpath=..")
|
||||
.locator('[data-testid="favorite-button"]');
|
||||
await expect(favoriteButton).toBeVisible();
|
||||
await favoriteButton.click();
|
||||
|
||||
// Check that the star is filled (favorited)
|
||||
const star = favoriteButton.locator("svg");
|
||||
await expect(star).toHaveClass(/fill-\[#6c55dc\]/);
|
||||
});
|
||||
|
||||
test("Remove app from favorite", async ({ po }) => {
|
||||
await po.setUp({ autoApprove: true });
|
||||
|
||||
// Create a test app
|
||||
await po.sendPrompt("create a test app");
|
||||
await po.goToAppsTab();
|
||||
|
||||
// Get the app name from the UI
|
||||
const appItems = await po.page.getByTestId(/^app-list-item-/).all();
|
||||
expect(appItems.length).toBeGreaterThan(0);
|
||||
const firstAppItem = appItems[0];
|
||||
const testId = await firstAppItem.getAttribute("data-testid");
|
||||
const appName = testId!.replace("app-list-item-", "");
|
||||
|
||||
// Get the app item
|
||||
const appItem = po.page.locator(`[data-testid="app-list-item-${appName}"]`);
|
||||
|
||||
// First, add to favorite
|
||||
const favoriteButton = appItem
|
||||
.locator("xpath=..")
|
||||
.locator('[data-testid="favorite-button"]');
|
||||
await favoriteButton.click();
|
||||
|
||||
// Check that the star is filled (favorited)
|
||||
const star = favoriteButton.locator("svg");
|
||||
await expect(star).toHaveClass(/fill-\[#6c55dc\]/);
|
||||
|
||||
// Now, remove from favorite
|
||||
const unfavoriteButton = appItem
|
||||
.locator("xpath=..")
|
||||
.locator('[data-testid="favorite-button"]');
|
||||
await expect(unfavoriteButton).toBeVisible();
|
||||
await unfavoriteButton.click();
|
||||
|
||||
// Check that the star is not filled (unfavorited)
|
||||
await expect(star).not.toHaveClass(/fill-\[#6c55dc\]/);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user