From d341cef4061a20291ee64b93d315e92b00164286 Mon Sep 17 00:00:00 2001
From: Eva Marco <evamarcod@gmail.com>
Date: Wed, 8 May 2024 17:30:47 +0200
Subject: [PATCH] :sparkles: Add basic dashboard pom and test

---
 .../data/dashboard/create-project.json        |  9 ++
 .../dashboard/get-project-files-empty.json    |  1 +
 .../data/dashboard/get-project-files.json     | 20 ++++
 .../data/dashboard/get-projects-new.json      | 18 ++++
 .../get-profile-logged-in-no-onboarding.json  | 26 ++++++
 frontend/playwright/ui/pages/DashboardPage.js | 93 +++++++++++++++++++
 .../playwright/ui/specs/dashboard.spec.js     | 44 +++++++++
 frontend/src/app/main/ui/components/link.cljs |  3 +-
 .../src/app/main/ui/dashboard/sidebar.cljs    |  1 +
 9 files changed, 214 insertions(+), 1 deletion(-)
 create mode 100644 frontend/playwright/data/dashboard/create-project.json
 create mode 100644 frontend/playwright/data/dashboard/get-project-files-empty.json
 create mode 100644 frontend/playwright/data/dashboard/get-project-files.json
 create mode 100644 frontend/playwright/data/dashboard/get-projects-new.json
 create mode 100644 frontend/playwright/data/logged-in-user/get-profile-logged-in-no-onboarding.json
 create mode 100644 frontend/playwright/ui/pages/DashboardPage.js
 create mode 100644 frontend/playwright/ui/specs/dashboard.spec.js

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")]]]