diff --git a/frontend/playwright/data/dashboard/create-project.json b/frontend/playwright/data/dashboard/create-project.json new file mode 100644 index 000000000..92566a65f --- /dev/null +++ b/frontend/playwright/data/dashboard/create-project.json @@ -0,0 +1,9 @@ +{ + "~:id": "~ue5a24d1b-ef1e-812f-8004-52bab84be6f7", + "~:team-id": "~uc7ce0794-0992-8105-8004-38e630f40f6", + "~:created-at": "~m1715266551088", + "~:modified-at": "~m1715266551088", + "~:is-default": false, + "~:name": "New Project 1", + "~:is-pinned": false +} diff --git a/frontend/playwright/data/dashboard/get-project-files-empty.json b/frontend/playwright/data/dashboard/get-project-files-empty.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/frontend/playwright/data/dashboard/get-project-files-empty.json @@ -0,0 +1 @@ +[] diff --git a/frontend/playwright/data/dashboard/get-project-files.json b/frontend/playwright/data/dashboard/get-project-files.json new file mode 100644 index 000000000..b0394aff1 --- /dev/null +++ b/frontend/playwright/data/dashboard/get-project-files.json @@ -0,0 +1,20 @@ +[ + { + "~:id": "~u8b479b80-e02d-8074-8004-4088dc6bfd11", + "~:project-id": "~uc7ce0794-0992-8105-8004-38e630f7920b", + "~:created-at": "~m1714045521389", + "~:modified-at": "~m1714045654874", + "~:name": "New File 2", + "~:revn": 1, + "~:is-shared": false + }, + { + "~:id": "~u95d6fdd8-48d8-8148-8004-38af910d2dbe", + "~:project-id": "~uc7ce0794-0992-8105-8004-38e630f7920b", + "~:created-at": "~m1713518796912", + "~:modified-at": "~m1713519762931", + "~:name": "New File 1", + "~:revn": 1, + "~:is-shared": false + } +] diff --git a/frontend/playwright/data/dashboard/get-projects-new.json b/frontend/playwright/data/dashboard/get-projects-new.json new file mode 100644 index 000000000..47c85eee4 --- /dev/null +++ b/frontend/playwright/data/dashboard/get-projects-new.json @@ -0,0 +1,18 @@ +[{ + "~:id": "~ue5a24d1b-ef1e-812f-8004-52bab84be6f7", + "~:team-id": "~uc7ce0794-0992-8105-8004-38e630f40f6d", + "~:created-at": "~m1715266551088", + "~:modified-at": "~m1715266551088", + "~:is-default": false, + "~:name": "New Project 1", + "~:is-pinned": false, + "~:count": 0 +}, +{ + "~:id": "~uc7ce0794-0992-8105-8004-38e630f7920b", + "~:team-id": "~uc7ce0794-0992-8105-8004-38e630f40f6d", + "~:created-at": "~m1713533116382", + "~:modified-at": "~m1713873823633", + "~:is-default": true, + "~:name": "Drafts" +}] diff --git a/frontend/playwright/data/logged-in-user/get-profile-logged-in-no-onboarding.json b/frontend/playwright/data/logged-in-user/get-profile-logged-in-no-onboarding.json new file mode 100644 index 000000000..0b416835f --- /dev/null +++ b/frontend/playwright/data/logged-in-user/get-profile-logged-in-no-onboarding.json @@ -0,0 +1,26 @@ +{ + "~:email": "foo@example.com", + "~:is-demo": false, + "~:auth-backend": "penpot", + "~:fullname": "Princesa Leia", + "~:modified-at": "~m1713533116365", + "~:is-active": true, + "~:default-project-id": "~uc7ce0794-0992-8105-8004-38e630f7920b", + "~:id": "~uc7ce0794-0992-8105-8004-38e630f29a9b", + "~:is-muted": false, + "~:default-team-id": "~uc7ce0794-0992-8105-8004-38e630f40f6d", + "~:created-at": "~m1713533116365", + "~:is-blocked": false, + "~:props": { + "~:nudge": { + "~:big": 10, + "~:small": 1 + }, + "~:v2-info-shown": true, + "~:viewed-tutorial?": false, + "~:viewed-walkthrough?": false, + "~:onboarding-viewed": true, + "~:builtin-templates-collapsed-status": + true + } +} diff --git a/frontend/playwright/ui/pages/DashboardPage.js b/frontend/playwright/ui/pages/DashboardPage.js new file mode 100644 index 000000000..285e47d95 --- /dev/null +++ b/frontend/playwright/ui/pages/DashboardPage.js @@ -0,0 +1,93 @@ +import { BaseWebSocketPage } from "./BaseWebSocketPage"; + +export class DashboardPage extends BaseWebSocketPage { + static async init(page) { + await BaseWebSocketPage.initWebSockets(page); + + await BaseWebSocketPage.mockRPC( + page, + "get-profile", + "logged-in-user/get-profile-logged-in-no-onboarding.json", + ); + await BaseWebSocketPage.mockRPC(page, "get-teams", "logged-in-user/get-teams-default.json"); + await BaseWebSocketPage.mockRPC( + page, + "get-font-variants?team-id=*", + "workspace/get-font-variants-empty.json", + ); + + await BaseWebSocketPage.mockRPC( + page, + "get-projects?team-id=*", + "logged-in-user/get-projects-default.json", + ); + await BaseWebSocketPage.mockRPC( + page, + "get-team-members?team-id=*", + "logged-in-user/get-team-members-your-penpot.json", + ); + await BaseWebSocketPage.mockRPC( + page, + "get-team-users?team-id=*", + "logged-in-user/get-team-users-single-user.json", + ); + await BaseWebSocketPage.mockRPC( + page, + "get-unread-comment-threads?team-id=*", + "logged-in-user/get-team-users-single-user.json", + ); + await BaseWebSocketPage.mockRPC( + page, + "get-team-recent-files?team-id=*", + "logged-in-user/get-team-recent-files-empty.json", + ); + await BaseWebSocketPage.mockRPC( + page, + "get-profiles-for-file-comments", + "workspace/get-profile-for-file-comments.json", + ); + await BaseWebSocketPage.mockRPC( + page, + "get-builtin-templates", + "logged-in-user/get-built-in-templates-empty.json", + ); + } + + static anyTeamId = "c7ce0794-0992-8105-8004-38e630f40f6d"; + + static draftProjectId = "c7ce0794-0992-8105-8004-38e630f7920b"; + + constructor(page) { + super(page); + this.titleLabel = page.getByRole("heading", { name: "Projects" }); + this.addProjectBtn = page.getByRole("button", { name: "+ NEW PROJECT" }); + this.projectName = page.getByText("Project 1"); + this.draftTitle = page.getByRole("heading", { name: "Drafts" }); + this.draftLink = page.getByTestId("drafts-link-sidebar"); + this.draftsFile = page.getByText(/New File 1/); + } + + async setupDraftsEmpty() { + await this.mockRPC("get-project-files?project-id=*", "dashboard/get-project-files-empty.json"); + } + + async setupDrafts() { + await this.mockRPC("get-project-files?project-id=*", "dashboard/get-project-files.json"); + } + + async setupNewProject() { + await this.mockRPC("create-project", "dashboard/create-project.json", { method: "POST" }); + await this.mockRPC("get-projects?team-id=*", "dashboard/get-projects-new.json"); + } + async goToWorkspace() { + await this.page.goto(`#/dashboard/team/${DashboardPage.anyTeamId}/projects`); + } + + async goToDrafts() { + await this.page.goto( + `#/dashboard/team/${DashboardPage.anyTeamId}/projects/${DashboardPage.draftProjectId}`, + ); + } +} + +export default DashboardPage; diff --git a/frontend/playwright/ui/specs/dashboard.spec.js b/frontend/playwright/ui/specs/dashboard.spec.js new file mode 100644 index 000000000..145c1321a --- /dev/null +++ b/frontend/playwright/ui/specs/dashboard.spec.js @@ -0,0 +1,44 @@ +import { test, expect } from "@playwright/test"; +import DashboardPage from "../pages/DashboardPage"; + +test.beforeEach(async ({ page }) => { + await DashboardPage.init(page); +}); + +test("Dashboad page has title ", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + + await dashboardPage.goToWorkspace(); + + await expect(dashboardPage.page).toHaveURL(/dashboard/); + await expect(dashboardPage.titleLabel).toBeVisible(); +}); + +test("User can create a new project", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.setupNewProject(); + + await dashboardPage.goToWorkspace(); + await dashboardPage.addProjectBtn.click(); + + await expect(dashboardPage.projectName).toBeVisible(); +}); + +test("User goes to draft page", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.setupDraftsEmpty(); + + await dashboardPage.goToWorkspace(); + await dashboardPage.draftLink.click(); + + await expect(dashboardPage.draftTitle).toBeVisible(); +}); + +test("User loads the draft page", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.setupDrafts(); + + await dashboardPage.goToDrafts(); + + await expect(dashboardPage.draftsFile).toBeVisible(); +}); diff --git a/frontend/src/app/main/ui/components/link.cljs b/frontend/src/app/main/ui/components/link.cljs index 4c48681bb..6ceee146b 100644 --- a/frontend/src/app/main/ui/components/link.cljs +++ b/frontend/src/app/main/ui/components/link.cljs @@ -12,7 +12,7 @@ (mf/defc link {::mf/wrap-props false} - [{:keys [action class data-test keyboard-action children]}] + [{:keys [action class data-test keyboard-action children data-testid]}] (let [keyboard-action (d/nilv keyboard-action action)] [:a {:on-click action :class class @@ -20,5 +20,6 @@ (when ^boolean (kbd/enter? event) (keyboard-action event))) :tab-index "0" + :data-testid data-testid :data-test data-test} children])) diff --git a/frontend/src/app/main/ui/dashboard/sidebar.cljs b/frontend/src/app/main/ui/dashboard/sidebar.cljs index 96d4c9df0..10cfd2f5c 100644 --- a/frontend/src/app/main/ui/dashboard/sidebar.cljs +++ b/frontend/src/app/main/ui/dashboard/sidebar.cljs @@ -783,6 +783,7 @@ [:li {:class (stl/css-case :current drafts? :sidebar-nav-item true)} [:& link {:action go-drafts + :data-testid "drafts-link-sidebar" :class (stl/css :sidebar-link) :keyboard-action go-drafts-with-key} [:span {:class (stl/css :element-title)} (tr "labels.drafts")]]]