💄 Reformat affected JS files

This commit is contained in:
Belén Albeza 2024-07-01 10:28:40 +02:00
parent 3efd5cb9e8
commit ecbedf847f
28 changed files with 720 additions and 285 deletions

View file

@ -14,12 +14,17 @@ export class MockWebSocketHelper extends EventTarget {
} }
this.#mocks.get(url).dispatchEvent(new MessageEvent("message", { data })); this.#mocks.get(url).dispatchEvent(new MessageEvent("message", { data }));
}); });
await page.exposeFunction("onMockWebSocketSpyClose", (url, code, reason) => { await page.exposeFunction(
"onMockWebSocketSpyClose",
(url, code, reason) => {
if (!this.#mocks.has(url)) { if (!this.#mocks.has(url)) {
throw new Error(`WebSocket with URL ${url} not found`); throw new Error(`WebSocket with URL ${url} not found`);
} }
this.#mocks.get(url).dispatchEvent(new CloseEvent("close", { code, reason })); this.#mocks
}); .get(url)
.dispatchEvent(new CloseEvent("close", { code, reason }));
},
);
await page.addInitScript({ path: "playwright/scripts/MockWebSocket.js" }); await page.addInitScript({ path: "playwright/scripts/MockWebSocket.js" });
} }

View file

@ -188,13 +188,18 @@ window.WebSocket = class MockWebSocket extends EventTarget {
mockClose(code, reason) { mockClose(code, reason) {
this.#readyState = MockWebSocket.CLOSED; this.#readyState = MockWebSocket.CLOSED;
this.dispatchEvent(new CloseEvent("close", { code: code || 1000, reason: reason || "" })); this.dispatchEvent(
new CloseEvent("close", { code: code || 1000, reason: reason || "" }),
);
return this; return this;
} }
send(data) { send(data) {
if (this.#readyState === MockWebSocket.CONNECTING) { if (this.#readyState === MockWebSocket.CONNECTING) {
throw new DOMException("InvalidStateError", "MockWebSocket is not connected"); throw new DOMException(
"InvalidStateError",
"MockWebSocket is not connected",
);
} }
if (this.#spyMessage) { if (this.#spyMessage) {
@ -203,7 +208,12 @@ window.WebSocket = class MockWebSocket extends EventTarget {
} }
close(code, reason) { close(code, reason) {
if (code && !Number.isInteger(code) && code !== 1000 && (code < 3000 || code > 4999)) { if (
code &&
!Number.isInteger(code) &&
code !== 1000 &&
(code < 3000 || code > 4999)
) {
throw new DOMException("InvalidAccessError", "Invalid code"); throw new DOMException("InvalidAccessError", "Invalid code");
} }
@ -214,7 +224,9 @@ window.WebSocket = class MockWebSocket extends EventTarget {
} }
} }
if ([MockWebSocket.CLOSED, MockWebSocket.CLOSING].includes(this.#readyState)) { if (
[MockWebSocket.CLOSED, MockWebSocket.CLOSING].includes(this.#readyState)
) {
return; return;
} }

View file

@ -4,7 +4,9 @@ export class BasePage {
throw new TypeError("Invalid page argument. Must be a Playwright page."); throw new TypeError("Invalid page argument. Must be a Playwright page.");
} }
if (typeof path !== "string" && !(path instanceof RegExp)) { if (typeof path !== "string" && !(path instanceof RegExp)) {
throw new TypeError("Invalid path argument. Must be a string or a RegExp."); throw new TypeError(
"Invalid path argument. Must be a string or a RegExp.",
);
} }
const url = typeof path === "string" ? `**/api/rpc/command/${path}` : path; const url = typeof path === "string" ? `**/api/rpc/command/${path}` : path;

View file

@ -5,7 +5,11 @@ export class DashboardPage extends BaseWebSocketPage {
static async init(page) { static async init(page) {
await BaseWebSocketPage.initWebSockets(page); await BaseWebSocketPage.initWebSockets(page);
await BaseWebSocketPage.mockRPC(page, "get-teams", "logged-in-user/get-teams-default.json"); await BaseWebSocketPage.mockRPC(
page,
"get-teams",
"logged-in-user/get-teams-default.json",
);
await BaseWebSocketPage.mockRPC( await BaseWebSocketPage.mockRPC(
page, page,
"get-font-variants?team-id=*", "get-font-variants?team-id=*",
@ -58,7 +62,9 @@ export class DashboardPage extends BaseWebSocketPage {
this.sidebar = page.getByTestId("dashboard-sidebar"); this.sidebar = page.getByTestId("dashboard-sidebar");
this.sidebarMenu = this.sidebar.getByRole("menu"); this.sidebarMenu = this.sidebar.getByRole("menu");
this.mainHeading = page.getByTestId("dashboard-header").getByRole("heading", { level: 1 }); this.mainHeading = page
.getByTestId("dashboard-header")
.getByRole("heading", { level: 1 });
this.addProjectButton = page.getByRole("button", { name: "+ NEW PROJECT" }); this.addProjectButton = page.getByRole("button", { name: "+ NEW PROJECT" });
this.projectName = page.getByText("Project 1"); this.projectName = page.getByText("Project 1");
@ -70,13 +76,20 @@ export class DashboardPage extends BaseWebSocketPage {
this.searchButton = page.getByRole("button", { name: "dashboard-search" }); this.searchButton = page.getByRole("button", { name: "dashboard-search" });
this.searchInput = page.getByPlaceholder("Search…"); this.searchInput = page.getByPlaceholder("Search…");
this.teamDropdown = this.sidebar.getByRole("button", { name: "Your Penpot" }); this.teamDropdown = this.sidebar.getByRole("button", {
this.userAccount = this.sidebar.getByRole("button", { name: /Princesa Leia/ }); name: "Your Penpot",
});
this.userAccount = this.sidebar.getByRole("button", {
name: /Princesa Leia/,
});
this.userProfileOption = this.sidebarMenu.getByText("Your account"); this.userProfileOption = this.sidebarMenu.getByText("Your account");
} }
async setupDraftsEmpty() { async setupDraftsEmpty() {
await this.mockRPC("get-project-files?project-id=*", "dashboard/get-project-files-empty.json"); await this.mockRPC(
"get-project-files?project-id=*",
"dashboard/get-project-files-empty.json",
);
} }
async setupSearchEmpty() { async setupSearchEmpty() {
@ -86,36 +99,74 @@ export class DashboardPage extends BaseWebSocketPage {
} }
async setupLibrariesEmpty() { async setupLibrariesEmpty() {
await this.mockRPC("get-team-shared-files?team-id=*", "dashboard/get-shared-files-empty.json"); await this.mockRPC(
"get-team-shared-files?team-id=*",
"dashboard/get-shared-files-empty.json",
);
} }
async setupDrafts() { async setupDrafts() {
await this.mockRPC("get-project-files?project-id=*", "dashboard/get-project-files.json"); await this.mockRPC(
"get-project-files?project-id=*",
"dashboard/get-project-files.json",
);
} }
async setupNewProject() { async setupNewProject() {
await this.mockRPC("create-project", "dashboard/create-project.json", { method: "POST" }); await this.mockRPC("create-project", "dashboard/create-project.json", {
await this.mockRPC("get-projects?team-id=*", "dashboard/get-projects-new.json"); method: "POST",
});
await this.mockRPC(
"get-projects?team-id=*",
"dashboard/get-projects-new.json",
);
} }
async setupDashboardFull() { async setupDashboardFull() {
await this.mockRPC("get-projects?team-id=*", "dashboard/get-projects-full.json"); await this.mockRPC(
await this.mockRPC("get-project-files?project-id=*", "dashboard/get-project-files.json"); "get-projects?team-id=*",
await this.mockRPC("get-team-shared-files?team-id=*", "dashboard/get-shared-files.json"); "dashboard/get-projects-full.json",
await this.mockRPC("get-team-shared-files?project-id=*", "dashboard/get-shared-files.json"); );
await this.mockRPC("get-team-recent-files?team-id=*", "dashboard/get-team-recent-files.json"); await this.mockRPC(
await this.mockRPC("get-font-variants?team-id=*", "dashboard/get-font-variants.json"); "get-project-files?project-id=*",
await this.mockRPC("search-files", "dashboard/search-files.json", { method: "POST" }); "dashboard/get-project-files.json",
);
await this.mockRPC(
"get-team-shared-files?team-id=*",
"dashboard/get-shared-files.json",
);
await this.mockRPC(
"get-team-shared-files?project-id=*",
"dashboard/get-shared-files.json",
);
await this.mockRPC(
"get-team-recent-files?team-id=*",
"dashboard/get-team-recent-files.json",
);
await this.mockRPC(
"get-font-variants?team-id=*",
"dashboard/get-font-variants.json",
);
await this.mockRPC("search-files", "dashboard/search-files.json", {
method: "POST",
});
await this.mockRPC("search-files", "dashboard/search-files.json"); await this.mockRPC("search-files", "dashboard/search-files.json");
await this.mockRPC("get-teams", "logged-in-user/get-teams-complete.json"); await this.mockRPC("get-teams", "logged-in-user/get-teams-complete.json");
} }
async setupAccessTokensEmpty() { async setupAccessTokensEmpty() {
await this.mockRPC("get-access-tokens", "dashboard/get-access-tokens-empty.json"); await this.mockRPC(
"get-access-tokens",
"dashboard/get-access-tokens-empty.json",
);
} }
async createAccessToken() { async createAccessToken() {
await this.mockRPC("create-access-token", "dashboard/create-access-token.json", { method: "POST" }); await this.mockRPC(
"create-access-token",
"dashboard/create-access-token.json",
{ method: "POST" },
);
} }
async setupAccessTokens() { async setupAccessTokens() {
@ -123,15 +174,24 @@ export class DashboardPage extends BaseWebSocketPage {
} }
async setupTeamInvitationsEmpty() { async setupTeamInvitationsEmpty() {
await this.mockRPC("get-team-invitations?team-id=*", "dashboard/get-team-invitations-empty.json"); await this.mockRPC(
"get-team-invitations?team-id=*",
"dashboard/get-team-invitations-empty.json",
);
} }
async setupTeamInvitations() { async setupTeamInvitations() {
await this.mockRPC("get-team-invitations?team-id=*", "dashboard/get-team-invitations.json"); await this.mockRPC(
"get-team-invitations?team-id=*",
"dashboard/get-team-invitations.json",
);
} }
async setupTeamWebhooksEmpty() { async setupTeamWebhooksEmpty() {
await this.mockRPC("get-webhooks?team-id=*", "dashboard/get-webhooks-empty.json"); await this.mockRPC(
"get-webhooks?team-id=*",
"dashboard/get-webhooks-empty.json",
);
} }
async setupTeamWebhooks() { async setupTeamWebhooks() {
@ -139,36 +199,53 @@ export class DashboardPage extends BaseWebSocketPage {
} }
async setupTeamSettings() { async setupTeamSettings() {
await this.mockRPC("get-team-stats?team-id=*", "dashboard/get-team-stats.json"); await this.mockRPC(
"get-team-stats?team-id=*",
"dashboard/get-team-stats.json",
);
} }
async goToDashboard() { async goToDashboard() {
await this.page.goto(`#/dashboard/team/${DashboardPage.anyTeamId}/projects`); await this.page.goto(
`#/dashboard/team/${DashboardPage.anyTeamId}/projects`,
);
await expect(this.mainHeading).toBeVisible(); await expect(this.mainHeading).toBeVisible();
} }
async goToSecondTeamDashboard() { async goToSecondTeamDashboard() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/projects`); await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/projects`,
);
} }
async goToSecondTeamMembersSection() { async goToSecondTeamMembersSection() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/members`); await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/members`,
);
} }
async goToSecondTeamInvitationsSection() { async goToSecondTeamInvitationsSection() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/invitations`); await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/invitations`,
);
} }
async goToSecondTeamWebhooksSection() { async goToSecondTeamWebhooksSection() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/webhooks`); await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/webhooks`,
);
} }
async goToSecondTeamWebhooksSection() { async goToSecondTeamWebhooksSection() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/webhooks`); await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/webhooks`,
);
} }
async goToSecondTeamSettingsSection() { async goToSecondTeamSettingsSection() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/settings`); await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/settings`,
);
} }
async goToSearch() { async goToSearch() {

View file

@ -6,9 +6,13 @@ export class LoginPage extends BasePage {
this.loginButton = page.getByRole("button", { name: "Login" }); this.loginButton = page.getByRole("button", { name: "Login" });
this.password = page.getByLabel("Password"); this.password = page.getByLabel("Password");
this.userName = page.getByLabel("Email"); this.userName = page.getByLabel("Email");
this.invalidCredentialsError = page.getByText("Email or password is incorrect"); this.invalidCredentialsError = page.getByText(
"Email or password is incorrect",
);
this.invalidEmailError = page.getByText("Enter a valid email please"); this.invalidEmailError = page.getByText("Enter a valid email please");
this.initialHeading = page.getByRole("heading", { name: "Log into my account" }); this.initialHeading = page.getByRole("heading", {
name: "Log into my account",
});
} }
async fillEmailAndPasswordInputs(email, password) { async fillEmailAndPasswordInputs(email, password) {
@ -25,17 +29,35 @@ export class LoginPage extends BasePage {
} }
async setupLoggedInUser() { async setupLoggedInUser() {
await this.mockRPC("get-profile", "logged-in-user/get-profile-logged-in.json"); await this.mockRPC(
"get-profile",
"logged-in-user/get-profile-logged-in.json",
);
await this.mockRPC("get-teams", "logged-in-user/get-teams-default.json"); await this.mockRPC("get-teams", "logged-in-user/get-teams-default.json");
await this.mockRPC("get-font-variants?team-id=*", "logged-in-user/get-font-variants-empty.json"); await this.mockRPC(
await this.mockRPC("get-projects?team-id=*", "logged-in-user/get-projects-default.json"); "get-font-variants?team-id=*",
await this.mockRPC("get-team-members?team-id=*", "logged-in-user/get-team-members-your-penpot.json"); "logged-in-user/get-font-variants-empty.json",
await this.mockRPC("get-team-users?team-id=*", "logged-in-user/get-team-users-single-user.json"); );
await this.mockRPC(
"get-projects?team-id=*",
"logged-in-user/get-projects-default.json",
);
await this.mockRPC(
"get-team-members?team-id=*",
"logged-in-user/get-team-members-your-penpot.json",
);
await this.mockRPC(
"get-team-users?team-id=*",
"logged-in-user/get-team-users-single-user.json",
);
await this.mockRPC( await this.mockRPC(
"get-unread-comment-threads?team-id=*", "get-unread-comment-threads?team-id=*",
"logged-in-user/get-team-users-single-user.json", "logged-in-user/get-team-users-single-user.json",
); );
await this.mockRPC("get-team-recent-files?team-id=*", "logged-in-user/get-team-recent-files-empty.json"); await this.mockRPC(
"get-team-recent-files?team-id=*",
"logged-in-user/get-team-recent-files-empty.json",
);
await this.mockRPC( await this.mockRPC(
"get-profiles-for-file-comments", "get-profiles-for-file-comments",
"logged-in-user/get-profiles-for-file-comments-empty.json", "logged-in-user/get-profiles-for-file-comments-empty.json",
@ -43,11 +65,18 @@ export class LoginPage extends BasePage {
} }
async setupLoginSuccess() { async setupLoginSuccess() {
await this.mockRPC("login-with-password", "logged-in-user/login-with-password-success.json"); await this.mockRPC(
"login-with-password",
"logged-in-user/login-with-password-success.json",
);
} }
async setupLoginError() { async setupLoginError() {
await this.mockRPC("login-with-password", "login-with-password-error.json", { status: 400 }); await this.mockRPC(
"login-with-password",
"login-with-password-error.json",
{ status: 400 },
);
} }
} }

View file

@ -3,42 +3,42 @@ import { BaseWebSocketPage } from "./BaseWebSocketPage";
export class OnboardingPage extends BaseWebSocketPage { export class OnboardingPage extends BaseWebSocketPage {
constructor(page) { constructor(page) {
super(page); super(page);
this.submitButton = page.getByRole("Button",{ name: "Next" }) this.submitButton = page.getByRole("Button", { name: "Next" });
} }
async fillOnboardingInputsStep1() { async fillOnboardingInputsStep1() {
await this.page.getByText('Personal').click(); await this.page.getByText("Personal").click();
await this.page.getByText('Select option').click(); await this.page.getByText("Select option").click();
await this.page.getByText('Testing before self-hosting').click(); await this.page.getByText("Testing before self-hosting").click();
await this.submitButton.click(); await this.submitButton.click();
} }
async fillOnboardingInputsStep2() { async fillOnboardingInputsStep2() {
await this.page.getByText('Figma').click(); await this.page.getByText("Figma").click();
await this.submitButton.click(); await this.submitButton.click();
} }
async fillOnboardingInputsStep3() { async fillOnboardingInputsStep3() {
await this.page.getByText('Select option').first().click(); await this.page.getByText("Select option").first().click();
await this.page.getByText('Product Managment').click(); await this.page.getByText("Product Managment").click();
await this.page.getByText('Select option').first().click(); await this.page.getByText("Select option").first().click();
await this.page.getByText('Director').click(); await this.page.getByText("Director").click();
await this.page.getByText('Select option').click(); await this.page.getByText("Select option").click();
await this.page.getByText('11-30').click(); await this.page.getByText("11-30").click();
await this.submitButton.click(); await this.submitButton.click();
} }
async fillOnboardingInputsStep4() { async fillOnboardingInputsStep4() {
await this.page.getByText('Other').click(); await this.page.getByText("Other").click();
await this.page.getByPlaceholder('Other (specify)').fill("Another"); await this.page.getByPlaceholder("Other (specify)").fill("Another");
await this.submitButton.click(); await this.submitButton.click();
} }
async fillOnboardingInputsStep5() { async fillOnboardingInputsStep5() {
await this.page.getByText('Event').click(); await this.page.getByText("Event").click();
} }
} }

View file

@ -15,12 +15,21 @@ export class ViewerPage extends BaseWebSocketPage {
} }
async setupLoggedInUser() { async setupLoggedInUser() {
await this.mockRPC("get-profile", "logged-in-user/get-profile-logged-in.json"); await this.mockRPC(
"get-profile",
"logged-in-user/get-profile-logged-in.json",
);
} }
async setupEmptyFile() { async setupEmptyFile() {
await this.mockRPC(/get\-view\-only\-bundle\?/, "viewer/get-view-only-bundle-empty-file.json"); await this.mockRPC(
await this.mockRPC("get-comment-threads?file-id=*", "workspace/get-comment-threads-empty.json"); /get\-view\-only\-bundle\?/,
"viewer/get-view-only-bundle-empty-file.json",
);
await this.mockRPC(
"get-comment-threads?file-id=*",
"workspace/get-comment-threads-empty.json",
);
await this.mockRPC( await this.mockRPC(
"get-file-fragment?file-id=*&fragment-id=*", "get-file-fragment?file-id=*&fragment-id=*",
"viewer/get-file-fragment-empty-file.json", "viewer/get-file-fragment-empty-file.json",
@ -28,24 +37,42 @@ export class ViewerPage extends BaseWebSocketPage {
} }
async setupFileWithSingleBoard() { async setupFileWithSingleBoard() {
await this.mockRPC(/get\-view\-only\-bundle\?/, "viewer/get-view-only-bundle-single-board.json"); await this.mockRPC(
await this.mockRPC("get-comment-threads?file-id=*", "workspace/get-comment-threads-empty.json"); /get\-view\-only\-bundle\?/,
"viewer/get-view-only-bundle-single-board.json",
);
await this.mockRPC(
"get-comment-threads?file-id=*",
"workspace/get-comment-threads-empty.json",
);
await this.mockRPC( await this.mockRPC(
"get-file-fragment?file-id=*&fragment-id=*", "get-file-fragment?file-id=*&fragment-id=*",
"viewer/get-file-fragment-single-board.json", "viewer/get-file-fragment-single-board.json",
); );
}; }
async setupFileWithComments() { async setupFileWithComments() {
await this.mockRPC(/get\-view\-only\-bundle\?/, "viewer/get-view-only-bundle-single-board.json"); await this.mockRPC(
await this.mockRPC("get-comment-threads?file-id=*", "workspace/get-comment-threads-not-empty.json"); /get\-view\-only\-bundle\?/,
"viewer/get-view-only-bundle-single-board.json",
);
await this.mockRPC(
"get-comment-threads?file-id=*",
"workspace/get-comment-threads-not-empty.json",
);
await this.mockRPC( await this.mockRPC(
"get-file-fragment?file-id=*&fragment-id=*", "get-file-fragment?file-id=*&fragment-id=*",
"viewer/get-file-fragment-single-board.json", "viewer/get-file-fragment-single-board.json",
); );
await this.mockRPC("get-comments?thread-id=*", "workspace/get-thread-comments.json"); await this.mockRPC(
await this.mockRPC("update-comment-thread-status", "workspace/update-comment-thread-status.json"); "get-comments?thread-id=*",
}; "workspace/get-thread-comments.json",
);
await this.mockRPC(
"update-comment-thread-status",
"workspace/update-comment-thread-status.json",
);
}
#ws = null; #ws = null;
@ -53,8 +80,13 @@ export class ViewerPage extends BaseWebSocketPage {
super(page); super(page);
} }
async goToViewer({ fileId = ViewerPage.anyFileId, pageId = ViewerPage.anyPageId } = {}) { async goToViewer({
await this.page.goto(`/#/view/${fileId}?page-id=${pageId}&section=interactions&index=0`); fileId = ViewerPage.anyFileId,
pageId = ViewerPage.anyPageId,
} = {}) {
await this.page.goto(
`/#/view/${fileId}?page-id=${pageId}&section=interactions&index=0`,
);
this.#ws = await this.waitForNotificationsWebSocket(); this.#ws = await this.waitForNotificationsWebSocket();
await this.#ws.mockOpen(); await this.#ws.mockOpen();
@ -79,8 +111,7 @@ export class ViewerPage extends BaseWebSocketPage {
async showCode(clickOptions = {}) { async showCode(clickOptions = {}) {
await this.page await this.page
.getByRole("button", { name: 'Inspect (G I)' }) .getByRole("button", { name: "Inspect (G I)" })
.click(clickOptions); .click(clickOptions);
} }
} }

View file

@ -11,7 +11,11 @@ export class WorkspacePage extends BaseWebSocketPage {
static async init(page) { static async init(page) {
await BaseWebSocketPage.initWebSockets(page); await BaseWebSocketPage.initWebSockets(page);
await BaseWebSocketPage.mockRPC(page, "get-profile", "logged-in-user/get-profile-logged-in.json"); await BaseWebSocketPage.mockRPC(
page,
"get-profile",
"logged-in-user/get-profile-logged-in.json",
);
await BaseWebSocketPage.mockRPC( await BaseWebSocketPage.mockRPC(
page, page,
"get-team-users?file-id=*", "get-team-users?file-id=*",
@ -22,8 +26,16 @@ export class WorkspacePage extends BaseWebSocketPage {
"get-comment-threads?file-id=*", "get-comment-threads?file-id=*",
"workspace/get-comment-threads-empty.json", "workspace/get-comment-threads-empty.json",
); );
await BaseWebSocketPage.mockRPC(page, "get-project?id=*", "workspace/get-project-default.json"); await BaseWebSocketPage.mockRPC(
await BaseWebSocketPage.mockRPC(page, "get-team?id=*", "workspace/get-team-default.json"); page,
"get-project?id=*",
"workspace/get-project-default.json",
);
await BaseWebSocketPage.mockRPC(
page,
"get-team?id=*",
"workspace/get-team-default.json",
);
await BaseWebSocketPage.mockRPC( await BaseWebSocketPage.mockRPC(
page, page,
"get-profiles-for-file-comments?file-id=*", "get-profiles-for-file-comments?file-id=*",
@ -40,12 +52,18 @@ export class WorkspacePage extends BaseWebSocketPage {
constructor(page) { constructor(page) {
super(page); super(page);
this.pageName = page.getByTestId("page-name"); this.pageName = page.getByTestId("page-name");
this.presentUserListItems = page.getByTestId("active-users-list").getByAltText("Princesa Leia"); this.presentUserListItems = page
.getByTestId("active-users-list")
.getByAltText("Princesa Leia");
this.viewport = page.getByTestId("viewport"); this.viewport = page.getByTestId("viewport");
this.rootShape = page.locator(`[id="shape-00000000-0000-0000-0000-000000000000"]`); this.rootShape = page.locator(
`[id="shape-00000000-0000-0000-0000-000000000000"]`,
);
this.toolbarOptions = page.getByTestId("toolbar-options"); this.toolbarOptions = page.getByTestId("toolbar-options");
this.rectShapeButton = page.getByRole("button", { name: "Rectangle (R)" }); this.rectShapeButton = page.getByRole("button", { name: "Rectangle (R)" });
this.toggleToolbarButton = page.getByRole("button", { name: "Toggle toolbar" }); this.toggleToolbarButton = page.getByRole("button", {
name: "Toggle toolbar",
});
this.colorpicker = page.getByTestId("colorpicker"); this.colorpicker = page.getByTestId("colorpicker");
this.layers = page.getByTestId("layer-tree"); this.layers = page.getByTestId("layer-tree");
this.palette = page.getByTestId("palette"); this.palette = page.getByTestId("palette");
@ -54,11 +72,18 @@ export class WorkspacePage extends BaseWebSocketPage {
this.selectionRect = page.getByTestId("workspace-selection-rect"); this.selectionRect = page.getByTestId("workspace-selection-rect");
this.horizontalScrollbar = page.getByTestId("horizontal-scrollbar"); this.horizontalScrollbar = page.getByTestId("horizontal-scrollbar");
this.librariesModal = page.getByTestId("libraries-modal"); this.librariesModal = page.getByTestId("libraries-modal");
this.togglePalettesVisibility = page.getByTestId("toggle-palettes-visibility"); this.togglePalettesVisibility = page.getByTestId(
"toggle-palettes-visibility",
);
} }
async goToWorkspace({ fileId = WorkspacePage.anyFileId, pageId = WorkspacePage.anyPageId } = {}) { async goToWorkspace({
await this.page.goto(`/#/workspace/${WorkspacePage.anyProjectId}/${fileId}?page-id=${pageId}`); fileId = WorkspacePage.anyFileId,
pageId = WorkspacePage.anyPageId,
} = {}) {
await this.page.goto(
`/#/workspace/${WorkspacePage.anyProjectId}/${fileId}?page-id=${pageId}`,
);
this.#ws = await this.waitForNotificationsWebSocket(); this.#ws = await this.waitForNotificationsWebSocket();
await this.#ws.mockOpen(); await this.#ws.mockOpen();
@ -79,10 +104,22 @@ export class WorkspacePage extends BaseWebSocketPage {
} }
async setupEmptyFile() { async setupEmptyFile() {
await this.mockRPC("get-profile", "logged-in-user/get-profile-logged-in.json"); await this.mockRPC(
await this.mockRPC("get-team-users?file-id=*", "logged-in-user/get-team-users-single-user.json"); "get-profile",
await this.mockRPC("get-comment-threads?file-id=*", "workspace/get-comment-threads-empty.json"); "logged-in-user/get-profile-logged-in.json",
await this.mockRPC("get-project?id=*", "workspace/get-project-default.json"); );
await this.mockRPC(
"get-team-users?file-id=*",
"logged-in-user/get-team-users-single-user.json",
);
await this.mockRPC(
"get-comment-threads?file-id=*",
"workspace/get-comment-threads-empty.json",
);
await this.mockRPC(
"get-project?id=*",
"workspace/get-project-default.json",
);
await this.mockRPC("get-team?id=*", "workspace/get-team-default.json"); await this.mockRPC("get-team?id=*", "workspace/get-team-default.json");
await this.mockRPC( await this.mockRPC(
"get-profiles-for-file-comments?file-id=*", "get-profiles-for-file-comments?file-id=*",
@ -93,9 +130,18 @@ export class WorkspacePage extends BaseWebSocketPage {
"get-file-object-thumbnails?file-id=*", "get-file-object-thumbnails?file-id=*",
"workspace/get-file-object-thumbnails-blank.json", "workspace/get-file-object-thumbnails-blank.json",
); );
await this.mockRPC("get-font-variants?team-id=*", "workspace/get-font-variants-empty.json"); await this.mockRPC(
await this.mockRPC("get-file-fragment?file-id=*", "workspace/get-file-fragment-blank.json"); "get-font-variants?team-id=*",
await this.mockRPC("get-file-libraries?file-id=*", "workspace/get-file-libraries-empty.json"); "workspace/get-font-variants-empty.json",
);
await this.mockRPC(
"get-file-fragment?file-id=*",
"workspace/get-file-fragment-blank.json",
);
await this.mockRPC(
"get-file-libraries?file-id=*",
"workspace/get-file-libraries-empty.json",
);
} }
async clickWithDragViewportAt(x, y, width, height) { async clickWithDragViewportAt(x, y, width, height) {
@ -132,14 +178,18 @@ export class WorkspacePage extends BaseWebSocketPage {
} }
async clickToggableLayer(name, clickOptions = {}) { async clickToggableLayer(name, clickOptions = {}) {
const layer = this.layers.getByTestId("layer-item").filter({ has: this.page.getByText(name) }); const layer = this.layers
.getByTestId("layer-item")
.filter({ has: this.page.getByText(name) });
await layer.getByRole("button").click(clickOptions); await layer.getByRole("button").click(clickOptions);
} }
async expectSelectedLayer(name) { async expectSelectedLayer(name) {
await expect(this.layers.getByTestId("layer-row").filter({ has: this.page.getByText(name) })).toHaveClass( await expect(
/selected/, this.layers
); .getByTestId("layer-row")
.filter({ has: this.page.getByText(name) }),
).toHaveClass(/selected/);
} }
async expectHiddenToolbarOptions() { async expectHiddenToolbarOptions() {
@ -163,19 +213,24 @@ export class WorkspacePage extends BaseWebSocketPage {
} }
async closeLibrariesModal(clickOptions = {}) { async closeLibrariesModal(clickOptions = {}) {
await this.librariesModal.getByRole("button", { name: "Close" }).click(clickOptions); await this.librariesModal
.getByRole("button", { name: "Close" })
.click(clickOptions);
} }
async clickColorPalette(clickOptions = {}) { async clickColorPalette(clickOptions = {}) {
await this.palette.getByRole("button", { name: "Color Palette (Alt+P)" }).click(clickOptions); await this.palette
.getByRole("button", { name: "Color Palette (Alt+P)" })
.click(clickOptions);
} }
async clickColorPalette(clickOptions = {}) { async clickColorPalette(clickOptions = {}) {
await this.palette.getByRole("button", { name: "Color Palette (Alt+P)" }).click(clickOptions); await this.palette
.getByRole("button", { name: "Color Palette (Alt+P)" })
.click(clickOptions);
} }
async clickTogglePalettesVisibility(clickOptions = {}) { async clickTogglePalettesVisibility(clickOptions = {}) {
await this.togglePalettesVisibility await this.togglePalettesVisibility.click(clickOptions);
.click(clickOptions);
} }
} }

View file

@ -6,7 +6,9 @@ test.beforeEach(async ({ page }) => {
}); });
// Fix for https://tree.taiga.io/project/penpot/issue/7549 // Fix for https://tree.taiga.io/project/penpot/issue/7549
test("Bug 7549 - User clicks on color swatch to display the color picker next to it", async ({ page }) => { test("Bug 7549 - User clicks on color swatch to display the color picker next to it", async ({
page,
}) => {
const workspacePage = new WorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page); await workspacePage.setupEmptyFile(page);

View file

@ -3,7 +3,11 @@ import DashboardPage from "../pages/DashboardPage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await DashboardPage.init(page); await DashboardPage.init(page);
await DashboardPage.mockRPC(page, "get-profile", "logged-in-user/get-profile-logged-in-no-onboarding.json"); await DashboardPage.mockRPC(
page,
"get-profile",
"logged-in-user/get-profile-logged-in-no-onboarding.json",
);
}); });
test("Dashboad page has title ", async ({ page }) => { test("Dashboad page has title ", async ({ page }) => {
@ -41,6 +45,10 @@ test("Lists files in the drafts page", async ({ page }) => {
await dashboardPage.goToDrafts(); await dashboardPage.goToDrafts();
await expect(dashboardPage.page.getByRole("button", { name: /New File 1/ })).toBeVisible(); await expect(
await expect(dashboardPage.page.getByRole("button", { name: /New File 2/ })).toBeVisible(); dashboardPage.page.getByRole("button", { name: /New File 1/ }),
).toBeVisible();
await expect(
dashboardPage.page.getByRole("button", { name: /New File 2/ }),
).toBeVisible();
}); });

View file

@ -12,7 +12,10 @@ const multipleAttributesPageId = `1795a568-0df0-8095-8004-7ba741f56be3`;
const setupFileWithMultipeConstraints = async (workspace) => { const setupFileWithMultipeConstraints = async (workspace) => {
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-multiple-constraints.json"); await workspace.mockRPC(
/get\-file\?/,
"design/get-file-multiple-constraints.json",
);
await workspace.mockRPC( await workspace.mockRPC(
"get-file-object-thumbnails?file-id=*", "get-file-object-thumbnails?file-id=*",
"design/get-file-object-thumbnails-multiple-constraints.json", "design/get-file-object-thumbnails-multiple-constraints.json",
@ -25,7 +28,10 @@ const setupFileWithMultipeConstraints = async (workspace) => {
const setupFileWithMultipeAttributes = async (workspace) => { const setupFileWithMultipeAttributes = async (workspace) => {
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-multiple-attributes.json"); await workspace.mockRPC(
/get\-file\?/,
"design/get-file-multiple-attributes.json",
);
await workspace.mockRPC( await workspace.mockRPC(
"get-file-object-thumbnails?file-id=*", "get-file-object-thumbnails?file-id=*",
"design/get-file-object-thumbnails-multiple-attributes.json", "design/get-file-object-thumbnails-multiple-attributes.json",
@ -47,9 +53,13 @@ test.describe("Constraints", () => {
await workspace.clickLeafLayer("Ellipse"); await workspace.clickLeafLayer("Ellipse");
await workspace.clickLeafLayer("Rectangle", { modifiers: ["Shift"] }); await workspace.clickLeafLayer("Rectangle", { modifiers: ["Shift"] });
const constraintVDropdown = workspace.page.getByTestId("constraint-v-select"); const constraintVDropdown = workspace.page.getByTestId(
"constraint-v-select",
);
await expect(constraintVDropdown).toContainText("Mixed"); await expect(constraintVDropdown).toContainText("Mixed");
const constraintHDropdown = workspace.page.getByTestId("constraint-h-select"); const constraintHDropdown = workspace.page.getByTestId(
"constraint-h-select",
);
await expect(constraintHDropdown).toContainText("Mixed"); await expect(constraintHDropdown).toContainText("Mixed");
expect(false); expect(false);
@ -57,7 +67,9 @@ test.describe("Constraints", () => {
}); });
test.describe("Multiple shapes attributes", () => { test.describe("Multiple shapes attributes", () => {
test("User selects multiple shapes with sames fills, strokes, shadows and blur", async ({ page }) => { test("User selects multiple shapes with sames fills, strokes, shadows and blur", async ({
page,
}) => {
const workspace = new WorkspacePage(page); const workspace = new WorkspacePage(page);
await setupFileWithMultipeConstraints(workspace); await setupFileWithMultipeConstraints(workspace);
await workspace.goToWorkspace({ await workspace.goToWorkspace({
@ -75,7 +87,9 @@ test.describe("Multiple shapes attributes", () => {
await expect(workspace.page.getByTestId("add-blur")).toBeVisible(); await expect(workspace.page.getByTestId("add-blur")).toBeVisible();
}); });
test("User selects multiple shapes with different fills, strokes, shadows and blur", async ({ page }) => { test("User selects multiple shapes with different fills, strokes, shadows and blur", async ({
page,
}) => {
const workspace = new WorkspacePage(page); const workspace = new WorkspacePage(page);
await setupFileWithMultipeAttributes(workspace); await setupFileWithMultipeAttributes(workspace);
await workspace.goToWorkspace({ await workspace.goToWorkspace({
@ -93,7 +107,9 @@ test.describe("Multiple shapes attributes", () => {
}); });
}); });
test("BUG 7760 - Layout losing properties when changing parents", async ({ page }) => { test("BUG 7760 - Layout losing properties when changing parents", async ({
page,
}) => {
const workspacePage = new WorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-7760.json"); await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-7760.json");
@ -101,7 +117,10 @@ test("BUG 7760 - Layout losing properties when changing parents", async ({ page
"get-file-fragment?file-id=*&fragment-id=*", "get-file-fragment?file-id=*&fragment-id=*",
"workspace/get-file-fragment-7760.json", "workspace/get-file-fragment-7760.json",
); );
await workspacePage.mockRPC("update-file?id=*", "workspace/update-file-create-rect.json"); await workspacePage.mockRPC(
"update-file?id=*",
"workspace/update-file-create-rect.json",
);
await workspacePage.goToWorkspace({ await workspacePage.goToWorkspace({
fileId: "cd90e028-326a-80b4-8004-7cdec16ffad5", fileId: "cd90e028-326a-80b4-8004-7cdec16ffad5",

View file

@ -8,7 +8,9 @@ test.beforeEach(async ({ page }) => {
await page.goto("/#/auth/login"); await page.goto("/#/auth/login");
}); });
test("User is redirected to the login page when logged out", async ({ page }) => { test("User is redirected to the login page when logged out", async ({
page,
}) => {
const loginPage = new LoginPage(page); const loginPage = new LoginPage(page);
await loginPage.setupLoggedInUser(); await loginPage.setupLoggedInUser();
@ -30,7 +32,9 @@ test.describe("Login form", () => {
await expect(loginPage.page).toHaveURL(/dashboard/); await expect(loginPage.page).toHaveURL(/dashboard/);
}); });
test("User gets error message when submitting an bad formatted email ", async ({ page }) => { test("User gets error message when submitting an bad formatted email ", async ({
page,
}) => {
const loginPage = new LoginPage(page); const loginPage = new LoginPage(page);
await loginPage.setupLoginSuccess(); await loginPage.setupLoginSuccess();
@ -39,11 +43,16 @@ test.describe("Login form", () => {
await expect(loginPage.invalidEmailError).toBeVisible(); await expect(loginPage.invalidEmailError).toBeVisible();
}); });
test("User gets error message when submitting wrong credentials", async ({ page }) => { test("User gets error message when submitting wrong credentials", async ({
page,
}) => {
const loginPage = new LoginPage(page); const loginPage = new LoginPage(page);
await loginPage.setupLoginError(); await loginPage.setupLoginError();
await loginPage.fillEmailAndPasswordInputs("test@example.com", "loremipsum"); await loginPage.fillEmailAndPasswordInputs(
"test@example.com",
"loremipsum",
);
await loginPage.clickLoginButton(); await loginPage.clickLoginButton();
await expect(loginPage.invalidCredentialsError).toBeVisible(); await expect(loginPage.invalidCredentialsError).toBeVisible();

View file

@ -1,31 +1,44 @@
import { test, expect } from "@playwright/test"; import { test, expect } from "@playwright/test";
import DashboardPage from "../pages/DashboardPage"; import DashboardPage from "../pages/DashboardPage";
import OnboardingPage from "../pages/OnboardingPage" import OnboardingPage from "../pages/OnboardingPage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await DashboardPage.init(page); await DashboardPage.init(page);
await DashboardPage.mockRPC(page, "get-profile", "logged-in-user/get-profile-logged-in.json"); await DashboardPage.mockRPC(
page,
"get-profile",
"logged-in-user/get-profile-logged-in.json",
);
}); });
test("User can complete the onboarding", async ({ page }) => { test("User can complete the onboarding", async ({ page }) => {
const dashboardPage = new DashboardPage(page); const dashboardPage = new DashboardPage(page);
const onboardingPage = new OnboardingPage(page); const onboardingPage = new OnboardingPage(page);
await dashboardPage.goToDashboard(); await dashboardPage.goToDashboard();
await expect(page.getByRole("heading", { name: "Help us get to know you" })).toBeVisible(); await expect(
page.getByRole("heading", { name: "Help us get to know you" }),
).toBeVisible();
await onboardingPage.fillOnboardingInputsStep1(); await onboardingPage.fillOnboardingInputsStep1();
await expect(page.getByRole("heading", { name: "Which one of these tools do" })).toBeVisible(); await expect(
page.getByRole("heading", { name: "Which one of these tools do" }),
).toBeVisible();
await onboardingPage.fillOnboardingInputsStep2(); await onboardingPage.fillOnboardingInputsStep2();
await expect(page.getByRole("heading", { name: "Tell us about your job" })).toBeVisible(); await expect(
page.getByRole("heading", { name: "Tell us about your job" }),
).toBeVisible();
await onboardingPage.fillOnboardingInputsStep3(); await onboardingPage.fillOnboardingInputsStep3();
await expect(page.getByRole("heading", { name: "Where would you like to get" })).toBeVisible(); await expect(
page.getByRole("heading", { name: "Where would you like to get" }),
).toBeVisible();
await onboardingPage.fillOnboardingInputsStep4(); await onboardingPage.fillOnboardingInputsStep4();
await expect(page.getByRole("heading", { name: "How did you hear about Penpot?" })).toBeVisible(); await expect(
page.getByRole("heading", { name: "How did you hear about Penpot?" }),
).toBeVisible();
await onboardingPage.fillOnboardingInputsStep5(); await onboardingPage.fillOnboardingInputsStep5();
await expect(page.getByRole("button", { name: "Start" })).toBeEnabled(); await expect(page.getByRole("button", { name: "Start" })).toBeEnabled();

View file

@ -6,7 +6,9 @@ test.beforeEach(async ({ page }) => {
}); });
test.describe("Layers tab", () => { test.describe("Layers tab", () => {
test("BUG 7466 - Layers tab height extends to the bottom when 'Pages' is collapsed", async ({ page }) => { test("BUG 7466 - Layers tab height extends to the bottom when 'Pages' is collapsed", async ({
page,
}) => {
const workspace = new WorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
@ -21,11 +23,19 @@ test.describe("Layers tab", () => {
}); });
test.describe("Assets tab", () => { test.describe("Assets tab", () => {
test("User adds a library and its automatically selected in the color palette", async ({ page }) => { test("User adds a library and its automatically selected in the color palette", async ({
page,
}) => {
const workspacePage = new WorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.mockRPC("link-file-to-library", "workspace/link-file-to-library.json"); await workspacePage.mockRPC(
await workspacePage.mockRPC("unlink-file-from-library", "workspace/unlink-file-from-library.json"); "link-file-to-library",
"workspace/link-file-to-library.json",
);
await workspacePage.mockRPC(
"unlink-file-from-library",
"workspace/unlink-file-from-library.json",
);
await workspacePage.mockRPC( await workspacePage.mockRPC(
"get-team-shared-files?team-id=*", "get-team-shared-files?team-id=*",
"workspace/get-team-shared-libraries-non-empty.json", "workspace/get-team-shared-libraries-non-empty.json",
@ -37,12 +47,17 @@ test.describe("Assets tab", () => {
await workspacePage.clickColorPalette(); await workspacePage.clickColorPalette();
await workspacePage.clickAssets(); await workspacePage.clickAssets();
// Now the get-file call should return a library // Now the get-file call should return a library
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-library.json"); await workspacePage.mockRPC(
/get\-file\?/,
"workspace/get-file-library.json",
);
await workspacePage.openLibrariesModal(); await workspacePage.openLibrariesModal();
await workspacePage.clickLibrary("Testing library 1"); await workspacePage.clickLibrary("Testing library 1");
await workspacePage.closeLibrariesModal(); await workspacePage.closeLibrariesModal();
await expect(workspacePage.palette.getByRole("button", { name: "test-color-187cd5" })).toBeVisible(); await expect(
workspacePage.palette.getByRole("button", { name: "test-color-187cd5" }),
).toBeVisible();
// Remove Testing library 1 // Remove Testing library 1
await workspacePage.openLibrariesModal(); await workspacePage.openLibrariesModal();
@ -50,7 +65,9 @@ test.describe("Assets tab", () => {
await workspacePage.closeLibrariesModal(); await workspacePage.closeLibrariesModal();
await expect( await expect(
workspacePage.palette.getByText("There are no color styles in your library yet"), workspacePage.palette.getByText(
"There are no color styles in your library yet",
),
).toBeVisible(); ).toBeVisible();
}); });
}); });

View file

@ -8,17 +8,23 @@ test.beforeEach(async ({ page }) => {
const singleBoardFileId = "dd5cc0bb-91ff-81b9-8004-77df9cd3edb1"; const singleBoardFileId = "dd5cc0bb-91ff-81b9-8004-77df9cd3edb1";
const singleBoardPageId = "dd5cc0bb-91ff-81b9-8004-77df9cd3edb2"; const singleBoardPageId = "dd5cc0bb-91ff-81b9-8004-77df9cd3edb2";
test("Comment is shown with scroll and valid position", async ({ page }) => { test("Comment is shown with scroll and valid position", async ({ page }) => {
const viewer = new ViewerPage(page); const viewer = new ViewerPage(page);
await viewer.setupLoggedInUser(); await viewer.setupLoggedInUser();
await viewer.setupFileWithComments(); await viewer.setupFileWithComments();
await viewer.goToViewer({ fileId: singleBoardFileId, pageId: singleBoardPageId }); await viewer.goToViewer({
fileId: singleBoardFileId,
pageId: singleBoardPageId,
});
await viewer.showComments(); await viewer.showComments();
await viewer.showCommentsThread(1); await viewer.showCommentsThread(1);
await expect(viewer.page.getByRole("textbox", { name: "Reply" })).toBeVisible(); await expect(
viewer.page.getByRole("textbox", { name: "Reply" }),
).toBeVisible();
await viewer.showCommentsThread(1); await viewer.showCommentsThread(1);
await viewer.showCommentsThread(2); await viewer.showCommentsThread(2);
await expect(viewer.page.getByRole("textbox", { name: "Reply" })).toBeVisible(); await expect(
viewer.page.getByRole("textbox", { name: "Reply" }),
).toBeVisible();
}); });

View file

@ -30,7 +30,10 @@ test("Updates URL with zoom type", async ({ page }) => {
await viewer.setupLoggedInUser(); await viewer.setupLoggedInUser();
await viewer.setupFileWithSingleBoard(viewer); await viewer.setupFileWithSingleBoard(viewer);
await viewer.goToViewer({ fileId: singleBoardFileId, pageId: singleBoardPageId }); await viewer.goToViewer({
fileId: singleBoardFileId,
pageId: singleBoardPageId,
});
await viewer.page.getByTitle("Zoom").click(); await viewer.page.getByTitle("Zoom").click();
await viewer.page.getByText(/Fit/).click(); await viewer.page.getByText(/Fit/).click();

View file

@ -15,20 +15,27 @@ test("User loads worskpace with empty file", async ({ page }) => {
await expect(workspacePage.pageName).toHaveText("Page 1"); await expect(workspacePage.pageName).toHaveText("Page 1");
}); });
test("User receives presence notifications updates in the workspace", async ({ page }) => { test("User receives presence notifications updates in the workspace", async ({
page,
}) => {
const workspacePage = new WorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();
await workspacePage.sendPresenceMessage(presenceFixture); await workspacePage.sendPresenceMessage(presenceFixture);
await expect(page.getByTestId("active-users-list").getByAltText("Princesa Leia")).toHaveCount(2); await expect(
page.getByTestId("active-users-list").getByAltText("Princesa Leia"),
).toHaveCount(2);
}); });
test("User draws a rect", async ({ page }) => { test("User draws a rect", async ({ page }) => {
const workspacePage = new WorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.mockRPC("update-file?id=*", "workspace/update-file-create-rect.json"); await workspacePage.mockRPC(
"update-file?id=*",
"workspace/update-file-create-rect.json",
);
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();
await workspacePage.rectShapeButton.click(); await workspacePage.rectShapeButton.click();
@ -42,8 +49,14 @@ test("User draws a rect", async ({ page }) => {
test("User makes a group", async ({ page }) => { test("User makes a group", async ({ page }) => {
const workspacePage = new WorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-not-empty.json"); await workspacePage.mockRPC(
await workspacePage.mockRPC("update-file?id=*", "workspace/update-file-create-rect.json"); /get\-file\?/,
"workspace/get-file-not-empty.json",
);
await workspacePage.mockRPC(
"update-file?id=*",
"workspace/update-file-create-rect.json",
);
await workspacePage.goToWorkspace({ await workspacePage.goToWorkspace({
fileId: "6191cd35-bb1f-81f7-8004-7cc63d087374", fileId: "6191cd35-bb1f-81f7-8004-7cc63d087374",
@ -54,7 +67,9 @@ test("User makes a group", async ({ page }) => {
await workspacePage.expectSelectedLayer("Group"); await workspacePage.expectSelectedLayer("Group");
}); });
test("Bug 7654 - Toolbar keeps toggling on and off on spacebar press", async ({ page }) => { test("Bug 7654 - Toolbar keeps toggling on and off on spacebar press", async ({
page,
}) => {
const workspacePage = new WorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();
@ -65,11 +80,19 @@ test("Bug 7654 - Toolbar keeps toggling on and off on spacebar press", async ({
await workspacePage.expectHiddenToolbarOptions(); await workspacePage.expectHiddenToolbarOptions();
}); });
test("Bug 7525 - User moves a scrollbar and no selciont rectangle appears", async ({ page }) => { test("Bug 7525 - User moves a scrollbar and no selciont rectangle appears", async ({
page,
}) => {
const workspacePage = new WorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-not-empty.json"); await workspacePage.mockRPC(
await workspacePage.mockRPC("update-file?id=*", "workspace/update-file-create-rect.json"); /get\-file\?/,
"workspace/get-file-not-empty.json",
);
await workspacePage.mockRPC(
"update-file?id=*",
"workspace/update-file-create-rect.json",
);
await workspacePage.goToWorkspace({ await workspacePage.goToWorkspace({
fileId: "6191cd35-bb1f-81f7-8004-7cc63d087374", fileId: "6191cd35-bb1f-81f7-8004-7cc63d087374",
@ -93,12 +116,23 @@ test("Bug 7525 - User moves a scrollbar and no selciont rectangle appears", asyn
await expect(workspacePage.selectionRect).not.toBeInViewport(); await expect(workspacePage.selectionRect).not.toBeInViewport();
}); });
test("User adds a library and its automatically selected in the color palette", async ({ page }) => { test("User adds a library and its automatically selected in the color palette", async ({
page,
}) => {
const workspacePage = new WorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.mockRPC("link-file-to-library", "workspace/link-file-to-library.json"); await workspacePage.mockRPC(
await workspacePage.mockRPC("unlink-file-from-library", "workspace/unlink-file-from-library.json"); "link-file-to-library",
await workspacePage.mockRPC("get-team-shared-files?team-id=*", "workspace/get-team-shared-libraries-non-empty.json"); "workspace/link-file-to-library.json",
);
await workspacePage.mockRPC(
"unlink-file-from-library",
"workspace/unlink-file-from-library.json",
);
await workspacePage.mockRPC(
"get-team-shared-files?team-id=*",
"workspace/get-team-shared-libraries-non-empty.json",
);
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();
@ -108,20 +142,28 @@ test("User adds a library and its automatically selected in the color palette",
// Now the get-file call should return a library // Now the get-file call should return a library
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-library.json"); await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-library.json");
await workspacePage.openLibrariesModal(); await workspacePage.openLibrariesModal();
await workspacePage.clickLibrary("Testing library 1") await workspacePage.clickLibrary("Testing library 1");
await workspacePage.closeLibrariesModal(); await workspacePage.closeLibrariesModal();
await expect(workspacePage.palette.getByRole("button", { name: "test-color-187cd5" })).toBeVisible(); await expect(
workspacePage.palette.getByRole("button", { name: "test-color-187cd5" }),
).toBeVisible();
// Remove Testing library 1 // Remove Testing library 1
await workspacePage.openLibrariesModal(); await workspacePage.openLibrariesModal();
await workspacePage.clickLibrary("Testing library 1") await workspacePage.clickLibrary("Testing library 1");
await workspacePage.closeLibrariesModal(); await workspacePage.closeLibrariesModal();
await expect(workspacePage.palette.getByText('There are no color styles in your library yet')).toBeVisible(); await expect(
workspacePage.palette.getByText(
"There are no color styles in your library yet",
),
).toBeVisible();
}); });
test("Bug 7489 - Workspace-palette items stay hidden when opening with keyboard-shortcut", async ({ page }) => { test("Bug 7489 - Workspace-palette items stay hidden when opening with keyboard-shortcut", async ({
page,
}) => {
const workspacePage = new WorkspacePage(page); const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(); await workspacePage.setupEmptyFile();
await workspacePage.goToWorkspace(); await workspacePage.goToWorkspace();
@ -129,5 +171,9 @@ test("Bug 7489 - Workspace-palette items stay hidden when opening with keyboard-
await workspacePage.clickTogglePalettesVisibility(); await workspacePage.clickTogglePalettesVisibility();
await workspacePage.page.keyboard.press("Alt+t"); await workspacePage.page.keyboard.press("Alt+t");
await expect(workspacePage.palette.getByText("There are no typography styles in your library yet")).toBeVisible(); await expect(
workspacePage.palette.getByText(
"There are no typography styles in your library yet",
),
).toBeVisible();
}); });

View file

@ -3,7 +3,11 @@ import DashboardPage from "../pages/DashboardPage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await DashboardPage.init(page); await DashboardPage.init(page);
await DashboardPage.mockRPC(page, "get-profile", "logged-in-user/get-profile-logged-in-no-onboarding.json"); await DashboardPage.mockRPC(
page,
"get-profile",
"logged-in-user/get-profile-logged-in-no-onboarding.json",
);
}); });
test("User goes to an empty dashboard", async ({ page }) => { test("User goes to an empty dashboard", async ({ page }) => {
@ -123,7 +127,9 @@ test("User goes to a full search page", async ({ page }) => {
await dashboardPage.searchInput.fill("3"); await dashboardPage.searchInput.fill("3");
await expect(dashboardPage.mainHeading).toHaveText("Search results"); await expect(dashboardPage.mainHeading).toHaveText("Search results");
await expect(dashboardPage.page.getByRole("button", { name: "New File 3" })).toBeVisible(); await expect(
dashboardPage.page.getByRole("button", { name: "New File 3" }),
).toBeVisible();
await expect(dashboardPage.page).toHaveScreenshot(); await expect(dashboardPage.page).toHaveScreenshot();
}); });
@ -157,7 +163,9 @@ test("User goes to password management section", async ({ page }) => {
await page.getByText("Password").click(); await page.getByText("Password").click();
await expect(page.getByRole("heading", { name: "Change Password" })).toBeVisible(); await expect(
page.getByRole("heading", { name: "Change Password" }),
).toBeVisible();
await expect(dashboardPage.page).toHaveScreenshot(); await expect(dashboardPage.page).toHaveScreenshot();
}); });

View file

@ -3,7 +3,6 @@ import { ViewerPage } from "../pages/ViewerPage";
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await ViewerPage.init(page); await ViewerPage.init(page);
}); });
const singleBoardFileId = "dd5cc0bb-91ff-81b9-8004-77df9cd3edb1"; const singleBoardFileId = "dd5cc0bb-91ff-81b9-8004-77df9cd3edb1";
@ -25,7 +24,10 @@ test("User goes to the Viewer", async ({ page }) => {
await viewerPage.setupLoggedInUser(); await viewerPage.setupLoggedInUser();
await viewerPage.setupFileWithSingleBoard(); await viewerPage.setupFileWithSingleBoard();
await viewerPage.goToViewer({ fileId: singleBoardFileId, pageId: singleBoardPageId }); await viewerPage.goToViewer({
fileId: singleBoardFileId,
pageId: singleBoardPageId,
});
await expect(viewerPage.page.getByTestId("penpot-logo-link")).toBeVisible(); await expect(viewerPage.page.getByTestId("penpot-logo-link")).toBeVisible();
await expect(viewerPage.page).toHaveScreenshot(); await expect(viewerPage.page).toHaveScreenshot();
@ -36,7 +38,10 @@ test("User goes to the Viewer and opens zoom modal", async ({ page }) => {
await viewerPage.setupLoggedInUser(); await viewerPage.setupLoggedInUser();
await viewerPage.setupFileWithSingleBoard(); await viewerPage.setupFileWithSingleBoard();
await viewerPage.goToViewer({ fileId: singleBoardFileId, pageId: singleBoardPageId }); await viewerPage.goToViewer({
fileId: singleBoardFileId,
pageId: singleBoardPageId,
});
await viewerPage.page.getByTitle("Zoom").click(); await viewerPage.page.getByTitle("Zoom").click();
@ -49,11 +54,16 @@ test("User goes to the Viewer Comments", async ({ page }) => {
await viewerPage.setupLoggedInUser(); await viewerPage.setupLoggedInUser();
await viewerPage.setupFileWithComments(); await viewerPage.setupFileWithComments();
await viewerPage.goToViewer({ fileId: singleBoardFileId, pageId: singleBoardPageId }); await viewerPage.goToViewer({
fileId: singleBoardFileId,
pageId: singleBoardPageId,
});
await viewerPage.showComments(); await viewerPage.showComments();
await viewerPage.showCommentsThread(1); await viewerPage.showCommentsThread(1);
await expect(viewerPage.page.getByRole("textbox", { name: "Reply" })).toBeVisible(); await expect(
viewerPage.page.getByRole("textbox", { name: "Reply" }),
).toBeVisible();
await expect(viewerPage.page).toHaveScreenshot(); await expect(viewerPage.page).toHaveScreenshot();
}); });
@ -63,14 +73,19 @@ test("User opens Viewer comment list", async ({ page }) => {
await viewerPage.setupLoggedInUser(); await viewerPage.setupLoggedInUser();
await viewerPage.setupFileWithComments(); await viewerPage.setupFileWithComments();
await viewerPage.goToViewer({ fileId: singleBoardFileId, pageId: singleBoardPageId }); await viewerPage.goToViewer({
fileId: singleBoardFileId,
pageId: singleBoardPageId,
});
await viewerPage.showComments(); await viewerPage.showComments();
await viewerPage.page.getByTestId("viewer-comments-dropdown").click(); await viewerPage.page.getByTestId("viewer-comments-dropdown").click();
await viewerPage.page.getByText("Show comments list").click(); await viewerPage.page.getByText("Show comments list").click();
await expect(viewerPage.page.getByRole("button", { name: "Show all comments" })).toBeVisible(); await expect(
viewerPage.page.getByRole("button", { name: "Show all comments" }),
).toBeVisible();
await expect(viewerPage.page).toHaveScreenshot(); await expect(viewerPage.page).toHaveScreenshot();
}); });
@ -79,7 +94,10 @@ test("User goes to the Viewer Inspect code", async ({ page }) => {
await viewerPage.setupLoggedInUser(); await viewerPage.setupLoggedInUser();
await viewerPage.setupFileWithComments(); await viewerPage.setupFileWithComments();
await viewerPage.goToViewer({ fileId: singleBoardFileId, pageId: singleBoardPageId }); await viewerPage.goToViewer({
fileId: singleBoardFileId,
pageId: singleBoardPageId,
});
await viewerPage.showCode(); await viewerPage.showCode();
@ -93,12 +111,17 @@ test("User goes to the Viewer Inspect code, code tab", async ({ page }) => {
await viewerPage.setupLoggedInUser(); await viewerPage.setupLoggedInUser();
await viewerPage.setupFileWithComments(); await viewerPage.setupFileWithComments();
await viewerPage.goToViewer({ fileId: singleBoardFileId, pageId: singleBoardPageId }); await viewerPage.goToViewer({
fileId: singleBoardFileId,
pageId: singleBoardPageId,
});
await viewerPage.showCode(); await viewerPage.showCode();
await viewerPage.page.getByTestId("code").click(); await viewerPage.page.getByTestId("code").click();
await expect(viewerPage.page.getByRole("button", { name: "Copy all code" })).toBeVisible(); await expect(
viewerPage.page.getByRole("button", { name: "Copy all code" }),
).toBeVisible();
await expect(viewerPage.page).toHaveScreenshot(); await expect(viewerPage.page).toHaveScreenshot();
}); });
@ -108,10 +131,15 @@ test("User opens Share modal", async ({ page }) => {
await viewerPage.setupLoggedInUser(); await viewerPage.setupLoggedInUser();
await viewerPage.setupFileWithSingleBoard(); await viewerPage.setupFileWithSingleBoard();
await viewerPage.goToViewer({ fileId: singleBoardFileId, pageId: singleBoardPageId }); await viewerPage.goToViewer({
fileId: singleBoardFileId,
pageId: singleBoardPageId,
});
await viewerPage.page.getByRole("button", { name: "Share" }).click(); await viewerPage.page.getByRole("button", { name: "Share" }).click();
await expect(viewerPage.page.getByRole("button", { name: "Get link" })).toBeVisible(); await expect(
viewerPage.page.getByRole("button", { name: "Get link" }),
).toBeVisible();
await expect(viewerPage.page).toHaveScreenshot(); await expect(viewerPage.page).toHaveScreenshot();
}); });

View file

@ -9,15 +9,20 @@ const setupFileWithAssets = async (workspace) => {
const fileId = "015fda4f-caa6-8103-8004-862a00dd4f31"; const fileId = "015fda4f-caa6-8103-8004-862a00dd4f31";
const pageId = "015fda4f-caa6-8103-8004-862a00ddbe94"; const pageId = "015fda4f-caa6-8103-8004-862a00ddbe94";
const fragments = { const fragments = {
"015fda4f-caa6-8103-8004-862a9e4b4d4b": "assets/get-file-fragment-with-assets-components.json", "015fda4f-caa6-8103-8004-862a9e4b4d4b":
"015fda4f-caa6-8103-8004-862a9e4ad279": "assets/get-file-fragmnet-with-assets-page.json", "assets/get-file-fragment-with-assets-components.json",
"015fda4f-caa6-8103-8004-862a9e4ad279":
"assets/get-file-fragmnet-with-assets-page.json",
}; };
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "assets/get-file-with-assets.json"); await workspace.mockRPC(/get\-file\?/, "assets/get-file-with-assets.json");
for (const [id, fixture] of Object.entries(fragments)) { for (const [id, fixture] of Object.entries(fragments)) {
await workspace.mockRPC(`get-file-fragment?file-id=*&fragment-id=${id}`, fixture); await workspace.mockRPC(
`get-file-fragment?file-id=*&fragment-id=${id}`,
fixture,
);
} }
return { fileId, pageId }; return { fileId, pageId };
@ -69,7 +74,10 @@ test.describe("Assets tab", () => {
test("Shows the libraries modal correctly", async ({ page }) => { test("Shows the libraries modal correctly", async ({ page }) => {
const workspace = new WorkspacePage(page); const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(); await workspace.setupEmptyFile();
await workspace.mockRPC("link-file-to-library", "workspace/link-file-to-library.json"); await workspace.mockRPC(
"link-file-to-library",
"workspace/link-file-to-library.json",
);
await workspace.mockRPC( await workspace.mockRPC(
"get-team-shared-files?team-id=*", "get-team-shared-files?team-id=*",
"workspace/get-team-shared-libraries-non-empty.json", "workspace/get-team-shared-libraries-non-empty.json",
@ -95,7 +103,9 @@ test.describe("Assets tab", () => {
await workspace.clickAssets(); await workspace.clickAssets();
await workspace.sidebar.getByRole("button", { name: "Components" }).click(); await workspace.sidebar.getByRole("button", { name: "Components" }).click();
await workspace.sidebar.getByRole("button", { name: "Colors" }).click(); await workspace.sidebar.getByRole("button", { name: "Colors" }).click();
await workspace.sidebar.getByRole("button", { name: "Typographies" }).click(); await workspace.sidebar
.getByRole("button", { name: "Typographies" })
.click();
await expect(workspace.page).toHaveScreenshot(); await expect(workspace.page).toHaveScreenshot();
@ -114,11 +124,19 @@ test.describe("Palette", () => {
await expect(workspace.page).toHaveScreenshot(); await expect(workspace.page).toHaveScreenshot();
await workspace.palette.getByRole("button", { name: "Typographies" }).click(); await workspace.palette
await expect(workspace.palette.getByText("Source Sans Pro Regular")).toBeVisible(); .getByRole("button", { name: "Typographies" })
.click();
await expect(
workspace.palette.getByText("Source Sans Pro Regular"),
).toBeVisible();
await expect(workspace.page).toHaveScreenshot(); await expect(workspace.page).toHaveScreenshot();
await workspace.palette.getByRole("button", { name: "Color Palette" }).click(); await workspace.palette
await expect(workspace.palette.getByRole("button", { name: "#7798ff" })).toBeVisible(); .getByRole("button", { name: "Color Palette" })
.click();
await expect(
workspace.palette.getByRole("button", { name: "#7798ff" }),
).toBeVisible();
}); });
}); });

View file

@ -34,7 +34,9 @@ async function findFiles(basePath, predicate, options = {}) {
return true; return true;
}; };
let files = await fs.readdir(basePath, { recursive: options.recursive ?? false }); let files = await fs.readdir(basePath, {
recursive: options.recursive ?? false,
});
files = files.map((path) => ph.join(basePath, path)); files = files.map((path) => ph.join(basePath, path));
return files; return files;
@ -232,7 +234,9 @@ async function readTranslations() {
lang = lang[0]; lang = lang[0];
} }
const content = await fs.readFile(`./translations/${filename}`, { encoding: "utf-8" }); const content = await fs.readFile(`./translations/${filename}`, {
encoding: "utf-8",
});
lang = lang.toLowerCase(); lang = lang.toLowerCase();
@ -291,15 +295,23 @@ async function generateSvgSprite(files, prefix) {
} }
async function generateSvgSprites() { async function generateSvgSprites() {
await fs.mkdir("resources/public/images/sprites/symbol/", { recursive: true }); await fs.mkdir("resources/public/images/sprites/symbol/", {
recursive: true,
});
const icons = await findFiles("resources/images/icons/", isSvgFile); const icons = await findFiles("resources/images/icons/", isSvgFile);
const iconsSprite = await generateSvgSprite(icons, "icon-"); const iconsSprite = await generateSvgSprite(icons, "icon-");
await fs.writeFile("resources/public/images/sprites/symbol/icons.svg", iconsSprite); await fs.writeFile(
"resources/public/images/sprites/symbol/icons.svg",
iconsSprite,
);
const cursors = await findFiles("resources/images/cursors/", isSvgFile); const cursors = await findFiles("resources/images/cursors/", isSvgFile);
const cursorsSprite = await generateSvgSprite(icons, "cursor-"); const cursorsSprite = await generateSvgSprite(icons, "cursor-");
await fs.writeFile("resources/public/images/sprites/symbol/cursors.svg", cursorsSprite); await fs.writeFile(
"resources/public/images/sprites/symbol/cursors.svg",
cursorsSprite,
);
} }
async function generateTemplates() { async function generateTemplates() {
@ -310,15 +322,23 @@ async function generateTemplates() {
const manifest = await readShadowManifest(); const manifest = await readShadowManifest();
let content; let content;
const iconsSprite = await fs.readFile("resources/public/images/sprites/symbol/icons.svg", "utf8"); const iconsSprite = await fs.readFile(
const cursorsSprite = await fs.readFile("resources/public/images/sprites/symbol/cursors.svg", "utf8"); "resources/public/images/sprites/symbol/icons.svg",
"utf8",
);
const cursorsSprite = await fs.readFile(
"resources/public/images/sprites/symbol/cursors.svg",
"utf8",
);
const partials = { const partials = {
"../public/images/sprites/symbol/icons.svg": iconsSprite, "../public/images/sprites/symbol/icons.svg": iconsSprite,
"../public/images/sprites/symbol/cursors.svg": cursorsSprite, "../public/images/sprites/symbol/cursors.svg": cursorsSprite,
}; };
const pluginRuntimeUri = const pluginRuntimeUri =
process.env.PENPOT_PLUGIN_DEV === "true" ? "http://localhost:4200" : "./plugins-runtime"; process.env.PENPOT_PLUGIN_DEV === "true"
? "http://localhost:4200"
: "./plugins-runtime";
content = await renderTemplate( content = await renderTemplate(
"resources/templates/index.mustache", "resources/templates/index.mustache",
@ -411,7 +431,10 @@ export async function copyAssets() {
await syncDirs("resources/images/", "resources/public/images/"); await syncDirs("resources/images/", "resources/public/images/");
await syncDirs("resources/fonts/", "resources/public/fonts/"); await syncDirs("resources/fonts/", "resources/public/fonts/");
await syncDirs("resources/plugins-runtime/", "resources/public/plugins-runtime/"); await syncDirs(
"resources/plugins-runtime/",
"resources/public/plugins-runtime/",
);
const end = process.hrtime(start); const end = process.hrtime(start);
log.info("done: copy assets", `(${ppt(end)})`); log.info("done: copy assets", `(${ppt(end)})`);

View file

@ -17,18 +17,21 @@ async function compileFile(path) {
const name = ph.basename(path, ".scss"); const name = ph.basename(path, ".scss");
const dest = `${dir}${ph.sep}${name}.css`; const dest = `${dir}${ph.sep}${name}.css`;
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
try { try {
const result = await compiler.compileAsync(path, { const result = await compiler.compileAsync(path, {
loadPaths: ["node_modules/animate.css", "resources/styles/common/", "resources/styles"], loadPaths: [
sourceMap: false "node_modules/animate.css",
"resources/styles/common/",
"resources/styles",
],
sourceMap: false,
}); });
// console.dir(result); // console.dir(result);
resolve({ resolve({
inputPath: path, inputPath: path,
outputPath: dest, outputPath: dest,
css: result.css css: result.css,
}); });
} catch (cause) { } catch (cause) {
// console.error(cause); // console.error(cause);
@ -78,7 +81,7 @@ async function postProcessFile(data, options) {
}); });
return Object.assign(data, { return Object.assign(data, {
css: result.css css: result.css,
}); });
} }
@ -87,11 +90,14 @@ async function compile(path, options) {
return await postProcessFile(result, options); return await postProcessFile(result, options);
} }
wpool.worker({ wpool.worker(
compileSass: compile {
}, { compileSass: compile,
},
{
onTerminate: async (code) => { onTerminate: async (code) => {
// log.info("worker: terminate"); // log.info("worker: terminate");
await compiler.dispose(); await compiler.dispose();
} },
}); },
);

View file

@ -4,7 +4,7 @@ import log from "fancy-log";
import * as h from "./_helpers.js"; import * as h from "./_helpers.js";
await h.compileStyles(); await h.compileStyles();
await h.copyAssets() await h.copyAssets();
await h.compileSvgSprites() await h.compileSvgSprites();
await h.compileTemplates(); await h.compileTemplates();
await h.compilePolyfills(); await h.compilePolyfills();

View file

@ -9,7 +9,10 @@ const port = 3000;
app.use(compression()); app.use(compression());
const staticPath = path.join(fileURLToPath(import.meta.url), "../../resources/public"); const staticPath = path.join(
fileURLToPath(import.meta.url),
"../../resources/public",
);
app.use(express.static(staticPath)); app.use(express.static(staticPath));
app.listen(port, () => { app.listen(port, () => {

View file

@ -1,26 +1,25 @@
const fs = require('fs').promises; const fs = require("fs").promises;
const gt = require("gettext-parser"); const gt = require("gettext-parser");
const path = require('path'); const path = require("path");
const util = require('node:util'); const util = require("node:util");
const execFile = util.promisify(require('node:child_process').execFile); const execFile = util.promisify(require("node:child_process").execFile);
async function processMsgId(msgId) { async function processMsgId(msgId) {
return execFile('grep', ['-r', '-o', msgId, './src']) return execFile("grep", ["-r", "-o", msgId, "./src"]).catch(() => {
.catch(()=> { return msgId}) return msgId;
});
} }
async function processFile(f) { async function processFile(f) {
const content = await fs.readFile(f); const content = await fs.readFile(f);
const data = gt.po.parse(content, "utf-8") const data = gt.po.parse(content, "utf-8");
const translations = data.translations['']; const translations = data.translations[""];
const badIds = []; const badIds = [];
for (const property in translations) { for (const property in translations) {
const data = await processMsgId(translations[property].msgid); const data = await processMsgId(translations[property].msgid);
if (data != null && data.stdout === undefined) { if (data != null && data.stdout === undefined) {
badIds.push(data) badIds.push(data);
} }
} }
@ -28,18 +27,18 @@ async function processFile(f) {
} }
async function cleanFile(f, badIds) { async function cleanFile(f, badIds) {
console.log ("\n\nDoing automatic cleanup") console.log("\n\nDoing automatic cleanup");
const content = await fs.readFile(f); const content = await fs.readFile(f);
const data = gt.po.parse(content, "utf-8"); const data = gt.po.parse(content, "utf-8");
const translations = data.translations['']; const translations = data.translations[""];
const keys = Object.keys(translations); const keys = Object.keys(translations);
for (const key of keys) { for (const key of keys) {
property = translations[key]; property = translations[key];
if (badIds.includes(property.msgid)) { if (badIds.includes(property.msgid)) {
console.log ('----> deleting', property.msgid) console.log("----> deleting", property.msgid);
delete data.translations[''][key]; delete data.translations[""][key];
} }
} }
@ -47,35 +46,49 @@ async function cleanFile(f, badIds) {
await fs.writeFile(f, buff); await fs.writeFile(f, buff);
} }
async function findExecutionTimeTranslations() { async function findExecutionTimeTranslations() {
const { stdout } = await execFile('grep', ['-r', '-h', '-F', '(tr (', './src']); const { stdout } = await execFile("grep", [
"-r",
"-h",
"-F",
"(tr (",
"./src",
]);
console.log(stdout); console.log(stdout);
} }
async function welcome() { async function welcome() {
console.log ('####################################################################') console.log(
console.log ('# UNUSED TRANSLATIONS FINDER #') "####################################################################",
console.log ('####################################################################') );
console.log ('\n'); console.log(
console.log ('DISCLAIMER: Some translations are only available at execution time.') "# UNUSED TRANSLATIONS FINDER #",
console.log (' This finder can\'t process them, so there can be') );
console.log (' false positives.\n') console.log(
console.log (' If you want to do an automatic clean anyway,') "####################################################################",
console.log (' call the script with:') );
console.log (' npm run find-unused-translations -- --clean') console.log("\n");
console.log (' For example:'); console.log(
console.log ('--------------------------------------------------------------------'); "DISCLAIMER: Some translations are only available at execution time.",
);
console.log(" This finder can't process them, so there can be");
console.log(" false positives.\n");
console.log(" If you want to do an automatic clean anyway,");
console.log(" call the script with:");
console.log(" npm run find-unused-translations -- --clean");
console.log(" For example:");
console.log(
"--------------------------------------------------------------------",
);
await findExecutionTimeTranslations(); await findExecutionTimeTranslations();
console.log ('--------------------------------------------------------------------'); console.log(
"--------------------------------------------------------------------",
);
} }
const doCleanup = process.argv.slice(2)[0] == "--clean"; const doCleanup = process.argv.slice(2)[0] == "--clean";
(async () => {
;(async () => {
await welcome(); await welcome();
const target = path.normalize("./translations/en.po"); const target = path.normalize("./translations/en.po");
const badIds = await processFile(target); const badIds = await processFile(target);
@ -87,4 +100,4 @@ const doCleanup = process.argv.slice(2)[0] == "--clean";
console.log(badId); console.log(badId);
} }
} }
})() })();

View file

@ -1,7 +1,7 @@
import {promises as fs} from 'fs'; import { promises as fs } from "fs";
import gt from 'gettext-parser'; import gt from "gettext-parser";
import l from 'lodash'; import l from "lodash";
import path from 'path'; import path from "path";
async function* getFiles(dir) { async function* getFiles(dir) {
const dirents = await fs.readdir(dir, { withFileTypes: true }); const dirents = await fs.readdir(dir, { withFileTypes: true });
@ -15,7 +15,7 @@ async function* getFiles(dir) {
} }
} }
;(async () => { (async () => {
const fileRe = /.+\.po$/; const fileRe = /.+\.po$/;
const target = path.normalize("./translations/"); const target = path.normalize("./translations/");
const parent = path.join(target, ".."); const parent = path.join(target, "..");
@ -24,8 +24,8 @@ async function* getFiles(dir) {
const entry = path.relative(parent, f); const entry = path.relative(parent, f);
console.log(`=> processing: ${entry}`); console.log(`=> processing: ${entry}`);
const content = await fs.readFile(f); const content = await fs.readFile(f);
const data = gt.po.parse(content, "utf-8") const data = gt.po.parse(content, "utf-8");
const buff = gt.po.compile(data, { sort: true }); const buff = gt.po.compile(data, { sort: true });
await fs.writeFile(f, buff); await fs.writeFile(f, buff);
} }
})() })();

View file

@ -11,7 +11,7 @@ let sass = null;
async function compileSassAll() { async function compileSassAll() {
const start = process.hrtime(); const start = process.hrtime();
log.info("init: compile styles") log.info("init: compile styles");
sass = await h.compileSassAll(worker); sass = await h.compileSassAll(worker);
let output = await h.concatSass(sass); let output = await h.concatSass(sass);
@ -37,12 +37,12 @@ async function compileSass(path) {
await fs.mkdir("./resources/public/css/", { recursive: true }); await fs.mkdir("./resources/public/css/", { recursive: true });
await compileSassAll(); await compileSassAll();
await h.copyAssets() await h.copyAssets();
await h.compileSvgSprites() await h.compileSvgSprites();
await h.compileTemplates(); await h.compileTemplates();
await h.compilePolyfills(); await h.compilePolyfills();
log.info("watch: scss src (~)") log.info("watch: scss src (~)");
h.watch("src", h.isSassFile, async function (path) { h.watch("src", h.isSassFile, async function (path) {
if (path.includes("common")) { if (path.includes("common")) {
@ -52,30 +52,34 @@ h.watch("src", h.isSassFile, async function (path) {
} }
}); });
log.info("watch: scss: resources (~)") log.info("watch: scss: resources (~)");
h.watch("resources/styles", h.isSassFile, async function (path) { h.watch("resources/styles", h.isSassFile, async function (path) {
log.info("changed:", path); log.info("changed:", path);
await compileSassAll() await compileSassAll();
}); });
log.info("watch: templates (~)") log.info("watch: templates (~)");
h.watch("resources/templates", null, async function (path) { h.watch("resources/templates", null, async function (path) {
log.info("changed:", path); log.info("changed:", path);
await h.compileTemplates(); await h.compileTemplates();
}); });
log.info("watch: translations (~)") log.info("watch: translations (~)");
h.watch("translations", null, async function (path) { h.watch("translations", null, async function (path) {
log.info("changed:", path); log.info("changed:", path);
await h.compileTemplates(); await h.compileTemplates();
}); });
log.info("watch: assets (~)") log.info("watch: assets (~)");
h.watch(["resources/images", "resources/fonts", "resources/plugins-runtime"], null, async function (path) { h.watch(
["resources/images", "resources/fonts", "resources/plugins-runtime"],
null,
async function (path) {
log.info("changed:", path); log.info("changed:", path);
await h.compileSvgSprites(); await h.compileSvgSprites();
await h.copyAssets(); await h.copyAssets();
await h.compileTemplates(); await h.compileTemplates();
}); },
);
worker.terminate(); worker.terminate();

View file

@ -4,16 +4,14 @@ import Components from "@target/components";
import Icons from "@target/icons"; import Icons from "@target/icons";
export default { export default {
title: 'Buttons/Simple Button', title: "Buttons/Simple Button",
component: Components.SimpleButton, component: Components.SimpleButton,
}; };
export const Default = { export const Default = {
render: () => ( render: () => (
<Components.StoryWrapper> <Components.StoryWrapper>
<Components.SimpleButton> <Components.SimpleButton>Simple Button</Components.SimpleButton>
Simple Button
</Components.SimpleButton>
</Components.StoryWrapper> </Components.StoryWrapper>
), ),
}; };
@ -27,4 +25,4 @@ export const WithIcon = {
</Components.SimpleButton> </Components.SimpleButton>
</Components.StoryWrapper> </Components.StoryWrapper>
), ),
} };