0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-06 14:50:20 -05:00

💄 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 }));
});
await page.exposeFunction("onMockWebSocketSpyClose", (url, code, reason) => {
if (!this.#mocks.has(url)) {
throw new Error(`WebSocket with URL ${url} not found`);
}
this.#mocks.get(url).dispatchEvent(new CloseEvent("close", { code, reason }));
});
await page.exposeFunction(
"onMockWebSocketSpyClose",
(url, code, reason) => {
if (!this.#mocks.has(url)) {
throw new Error(`WebSocket with URL ${url} not found`);
}
this.#mocks
.get(url)
.dispatchEvent(new CloseEvent("close", { code, reason }));
},
);
await page.addInitScript({ path: "playwright/scripts/MockWebSocket.js" });
}

View file

@ -188,13 +188,18 @@ window.WebSocket = class MockWebSocket extends EventTarget {
mockClose(code, reason) {
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;
}
send(data) {
if (this.#readyState === MockWebSocket.CONNECTING) {
throw new DOMException("InvalidStateError", "MockWebSocket is not connected");
throw new DOMException(
"InvalidStateError",
"MockWebSocket is not connected",
);
}
if (this.#spyMessage) {
@ -203,7 +208,12 @@ window.WebSocket = class MockWebSocket extends EventTarget {
}
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");
}
@ -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;
}

View file

@ -4,7 +4,9 @@ export class BasePage {
throw new TypeError("Invalid page argument. Must be a Playwright page.");
}
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;

View file

@ -5,7 +5,11 @@ export class DashboardPage extends BaseWebSocketPage {
static async init(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(
page,
"get-font-variants?team-id=*",
@ -58,7 +62,9 @@ export class DashboardPage extends BaseWebSocketPage {
this.sidebar = page.getByTestId("dashboard-sidebar");
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.projectName = page.getByText("Project 1");
@ -70,13 +76,20 @@ export class DashboardPage extends BaseWebSocketPage {
this.searchButton = page.getByRole("button", { name: "dashboard-search" });
this.searchInput = page.getByPlaceholder("Search…");
this.teamDropdown = this.sidebar.getByRole("button", { name: "Your Penpot" });
this.userAccount = this.sidebar.getByRole("button", { name: /Princesa Leia/ });
this.teamDropdown = this.sidebar.getByRole("button", {
name: "Your Penpot",
});
this.userAccount = this.sidebar.getByRole("button", {
name: /Princesa Leia/,
});
this.userProfileOption = this.sidebarMenu.getByText("Your account");
}
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() {
@ -86,36 +99,74 @@ export class DashboardPage extends BaseWebSocketPage {
}
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() {
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() {
await this.mockRPC("create-project", "dashboard/create-project.json", { method: "POST" });
await this.mockRPC("get-projects?team-id=*", "dashboard/get-projects-new.json");
await this.mockRPC("create-project", "dashboard/create-project.json", {
method: "POST",
});
await this.mockRPC(
"get-projects?team-id=*",
"dashboard/get-projects-new.json",
);
}
async setupDashboardFull() {
await this.mockRPC("get-projects?team-id=*", "dashboard/get-projects-full.json");
await this.mockRPC("get-project-files?project-id=*", "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(
"get-projects?team-id=*",
"dashboard/get-projects-full.json",
);
await this.mockRPC(
"get-project-files?project-id=*",
"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("get-teams", "logged-in-user/get-teams-complete.json");
}
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() {
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() {
@ -123,15 +174,24 @@ export class DashboardPage extends BaseWebSocketPage {
}
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() {
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() {
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() {
@ -139,36 +199,53 @@ export class DashboardPage extends BaseWebSocketPage {
}
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() {
await this.page.goto(`#/dashboard/team/${DashboardPage.anyTeamId}/projects`);
await this.page.goto(
`#/dashboard/team/${DashboardPage.anyTeamId}/projects`,
);
await expect(this.mainHeading).toBeVisible();
}
async goToSecondTeamDashboard() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/projects`);
await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/projects`,
);
}
async goToSecondTeamMembersSection() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/members`);
await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/members`,
);
}
async goToSecondTeamInvitationsSection() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/invitations`);
await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/invitations`,
);
}
async goToSecondTeamWebhooksSection() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/webhooks`);
await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/webhooks`,
);
}
async goToSecondTeamWebhooksSection() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/webhooks`);
await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/webhooks`,
);
}
async goToSecondTeamSettingsSection() {
await this.page.goto(`#/dashboard/team/${DashboardPage.secondTeamId}/settings`);
await this.page.goto(
`#/dashboard/team/${DashboardPage.secondTeamId}/settings`,
);
}
async goToSearch() {

View file

@ -6,9 +6,13 @@ export class LoginPage extends BasePage {
this.loginButton = page.getByRole("button", { name: "Login" });
this.password = page.getByLabel("Password");
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.initialHeading = page.getByRole("heading", { name: "Log into my account" });
this.initialHeading = page.getByRole("heading", {
name: "Log into my account",
});
}
async fillEmailAndPasswordInputs(email, password) {
@ -25,17 +29,35 @@ export class LoginPage extends BasePage {
}
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-font-variants?team-id=*", "logged-in-user/get-font-variants-empty.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(
"get-font-variants?team-id=*",
"logged-in-user/get-font-variants-empty.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(
"get-unread-comment-threads?team-id=*",
"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(
"get-profiles-for-file-comments",
"logged-in-user/get-profiles-for-file-comments-empty.json",
@ -43,11 +65,18 @@ export class LoginPage extends BasePage {
}
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() {
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 {
constructor(page) {
super(page);
this.submitButton = page.getByRole("Button",{ name: "Next" })
this.submitButton = page.getByRole("Button", { name: "Next" });
}
async fillOnboardingInputsStep1() {
await this.page.getByText('Personal').click();
await this.page.getByText('Select option').click();
await this.page.getByText('Testing before self-hosting').click();
await this.page.getByText("Personal").click();
await this.page.getByText("Select option").click();
await this.page.getByText("Testing before self-hosting").click();
await this.submitButton.click();
}
async fillOnboardingInputsStep2() {
await this.page.getByText('Figma').click();
await this.page.getByText("Figma").click();
await this.submitButton.click();
}
async fillOnboardingInputsStep3() {
await this.page.getByText('Select option').first().click();
await this.page.getByText('Product Managment').click();
await this.page.getByText('Select option').first().click();
await this.page.getByText('Director').click();
await this.page.getByText('Select option').click();
await this.page.getByText('11-30').click();
await this.page.getByText("Select option").first().click();
await this.page.getByText("Product Managment").click();
await this.page.getByText("Select option").first().click();
await this.page.getByText("Director").click();
await this.page.getByText("Select option").click();
await this.page.getByText("11-30").click();
await this.submitButton.click();
}
async fillOnboardingInputsStep4() {
await this.page.getByText('Other').click();
await this.page.getByPlaceholder('Other (specify)').fill("Another");
await this.page.getByText("Other").click();
await this.page.getByPlaceholder("Other (specify)").fill("Another");
await this.submitButton.click();
}
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() {
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() {
await this.mockRPC(/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(
/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(
"get-file-fragment?file-id=*&fragment-id=*",
"viewer/get-file-fragment-empty-file.json",
@ -28,24 +37,42 @@ export class ViewerPage extends BaseWebSocketPage {
}
async setupFileWithSingleBoard() {
await this.mockRPC(/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(
/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(
"get-file-fragment?file-id=*&fragment-id=*",
"viewer/get-file-fragment-single-board.json",
);
};
}
async setupFileWithComments() {
await this.mockRPC(/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(
/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(
"get-file-fragment?file-id=*&fragment-id=*",
"viewer/get-file-fragment-single-board.json",
);
await this.mockRPC("get-comments?thread-id=*", "workspace/get-thread-comments.json");
await this.mockRPC("update-comment-thread-status", "workspace/update-comment-thread-status.json");
};
await this.mockRPC(
"get-comments?thread-id=*",
"workspace/get-thread-comments.json",
);
await this.mockRPC(
"update-comment-thread-status",
"workspace/update-comment-thread-status.json",
);
}
#ws = null;
@ -53,8 +80,13 @@ export class ViewerPage extends BaseWebSocketPage {
super(page);
}
async goToViewer({ fileId = ViewerPage.anyFileId, pageId = ViewerPage.anyPageId } = {}) {
await this.page.goto(`/#/view/${fileId}?page-id=${pageId}&section=interactions&index=0`);
async goToViewer({
fileId = ViewerPage.anyFileId,
pageId = ViewerPage.anyPageId,
} = {}) {
await this.page.goto(
`/#/view/${fileId}?page-id=${pageId}&section=interactions&index=0`,
);
this.#ws = await this.waitForNotificationsWebSocket();
await this.#ws.mockOpen();
@ -72,15 +104,14 @@ export class ViewerPage extends BaseWebSocketPage {
async showCommentsThread(number, clickOptions = {}) {
await this.page
.getByTestId("floating-thread-bubble")
.filter({ hasText: number.toString() })
.click(clickOptions);
.getByTestId("floating-thread-bubble")
.filter({ hasText: number.toString() })
.click(clickOptions);
}
async showCode(clickOptions = {}) {
await this.page
.getByRole("button", { name: 'Inspect (G I)' })
.getByRole("button", { name: "Inspect (G I)" })
.click(clickOptions);
}
}

View file

@ -11,7 +11,11 @@ export class WorkspacePage extends BaseWebSocketPage {
static async init(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(
page,
"get-team-users?file-id=*",
@ -22,8 +26,16 @@ export class WorkspacePage extends BaseWebSocketPage {
"get-comment-threads?file-id=*",
"workspace/get-comment-threads-empty.json",
);
await BaseWebSocketPage.mockRPC(page, "get-project?id=*", "workspace/get-project-default.json");
await BaseWebSocketPage.mockRPC(page, "get-team?id=*", "workspace/get-team-default.json");
await BaseWebSocketPage.mockRPC(
page,
"get-project?id=*",
"workspace/get-project-default.json",
);
await BaseWebSocketPage.mockRPC(
page,
"get-team?id=*",
"workspace/get-team-default.json",
);
await BaseWebSocketPage.mockRPC(
page,
"get-profiles-for-file-comments?file-id=*",
@ -40,12 +52,18 @@ export class WorkspacePage extends BaseWebSocketPage {
constructor(page) {
super(page);
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.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.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.layers = page.getByTestId("layer-tree");
this.palette = page.getByTestId("palette");
@ -54,11 +72,18 @@ export class WorkspacePage extends BaseWebSocketPage {
this.selectionRect = page.getByTestId("workspace-selection-rect");
this.horizontalScrollbar = page.getByTestId("horizontal-scrollbar");
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 } = {}) {
await this.page.goto(`/#/workspace/${WorkspacePage.anyProjectId}/${fileId}?page-id=${pageId}`);
async goToWorkspace({
fileId = WorkspacePage.anyFileId,
pageId = WorkspacePage.anyPageId,
} = {}) {
await this.page.goto(
`/#/workspace/${WorkspacePage.anyProjectId}/${fileId}?page-id=${pageId}`,
);
this.#ws = await this.waitForNotificationsWebSocket();
await this.#ws.mockOpen();
@ -79,10 +104,22 @@ export class WorkspacePage extends BaseWebSocketPage {
}
async setupEmptyFile() {
await this.mockRPC("get-profile", "logged-in-user/get-profile-logged-in.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-profile",
"logged-in-user/get-profile-logged-in.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-profiles-for-file-comments?file-id=*",
@ -93,9 +130,18 @@ export class WorkspacePage extends BaseWebSocketPage {
"get-file-object-thumbnails?file-id=*",
"workspace/get-file-object-thumbnails-blank.json",
);
await this.mockRPC("get-font-variants?team-id=*", "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");
await this.mockRPC(
"get-font-variants?team-id=*",
"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) {
@ -132,14 +178,18 @@ export class WorkspacePage extends BaseWebSocketPage {
}
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);
}
async expectSelectedLayer(name) {
await expect(this.layers.getByTestId("layer-row").filter({ has: this.page.getByText(name) })).toHaveClass(
/selected/,
);
await expect(
this.layers
.getByTestId("layer-row")
.filter({ has: this.page.getByText(name) }),
).toHaveClass(/selected/);
}
async expectHiddenToolbarOptions() {
@ -163,19 +213,24 @@ export class WorkspacePage extends BaseWebSocketPage {
}
async closeLibrariesModal(clickOptions = {}) {
await this.librariesModal.getByRole("button", { name: "Close" }).click(clickOptions);
await this.librariesModal
.getByRole("button", { name: "Close" })
.click(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 = {}) {
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 = {}) {
await this.togglePalettesVisibility
.click(clickOptions);
await this.togglePalettesVisibility.click(clickOptions);
}
}

View file

@ -6,7 +6,9 @@ test.beforeEach(async ({ page }) => {
});
// 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);
await workspacePage.setupEmptyFile(page);

View file

@ -3,7 +3,11 @@ import DashboardPage from "../pages/DashboardPage";
test.beforeEach(async ({ 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 }) => {
@ -41,6 +45,10 @@ test("Lists files in the drafts page", async ({ page }) => {
await dashboardPage.goToDrafts();
await expect(dashboardPage.page.getByRole("button", { name: /New File 1/ })).toBeVisible();
await expect(dashboardPage.page.getByRole("button", { name: /New File 2/ })).toBeVisible();
await expect(
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) => {
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(
"get-file-object-thumbnails?file-id=*",
"design/get-file-object-thumbnails-multiple-constraints.json",
@ -25,7 +28,10 @@ const setupFileWithMultipeConstraints = async (workspace) => {
const setupFileWithMultipeAttributes = async (workspace) => {
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(
"get-file-object-thumbnails?file-id=*",
"design/get-file-object-thumbnails-multiple-attributes.json",
@ -47,9 +53,13 @@ test.describe("Constraints", () => {
await workspace.clickLeafLayer("Ellipse");
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");
const constraintHDropdown = workspace.page.getByTestId("constraint-h-select");
const constraintHDropdown = workspace.page.getByTestId(
"constraint-h-select",
);
await expect(constraintHDropdown).toContainText("Mixed");
expect(false);
@ -57,7 +67,9 @@ test.describe("Constraints", () => {
});
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);
await setupFileWithMultipeConstraints(workspace);
await workspace.goToWorkspace({
@ -75,7 +87,9 @@ test.describe("Multiple shapes attributes", () => {
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);
await setupFileWithMultipeAttributes(workspace);
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);
await workspacePage.setupEmptyFile();
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=*",
"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({
fileId: "cd90e028-326a-80b4-8004-7cdec16ffad5",

View file

@ -8,7 +8,9 @@ test.beforeEach(async ({ page }) => {
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);
await loginPage.setupLoggedInUser();
@ -30,7 +32,9 @@ test.describe("Login form", () => {
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);
await loginPage.setupLoginSuccess();
@ -39,11 +43,16 @@ test.describe("Login form", () => {
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);
await loginPage.setupLoginError();
await loginPage.fillEmailAndPasswordInputs("test@example.com", "loremipsum");
await loginPage.fillEmailAndPasswordInputs(
"test@example.com",
"loremipsum",
);
await loginPage.clickLoginButton();
await expect(loginPage.invalidCredentialsError).toBeVisible();

View file

@ -1,31 +1,44 @@
import { test, expect } from "@playwright/test";
import DashboardPage from "../pages/DashboardPage";
import OnboardingPage from "../pages/OnboardingPage"
import OnboardingPage from "../pages/OnboardingPage";
test.beforeEach(async ({ 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 }) => {
const dashboardPage = new DashboardPage(page);
const onboardingPage = new OnboardingPage(page);
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 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 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 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 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 expect(page.getByRole("button", { name: "Start" })).toBeEnabled();

View file

@ -6,7 +6,9 @@ test.beforeEach(async ({ page }) => {
});
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);
await workspace.setupEmptyFile();
@ -21,11 +23,19 @@ test.describe("Layers 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);
await workspacePage.setupEmptyFile();
await workspacePage.mockRPC("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(
"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(
"get-team-shared-files?team-id=*",
"workspace/get-team-shared-libraries-non-empty.json",
@ -37,12 +47,17 @@ test.describe("Assets tab", () => {
await workspacePage.clickColorPalette();
await workspacePage.clickAssets();
// 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.clickLibrary("Testing library 1");
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
await workspacePage.openLibrariesModal();
@ -50,7 +65,9 @@ test.describe("Assets tab", () => {
await workspacePage.closeLibrariesModal();
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();
});
});

View file

@ -8,17 +8,23 @@ test.beforeEach(async ({ page }) => {
const singleBoardFileId = "dd5cc0bb-91ff-81b9-8004-77df9cd3edb1";
const singleBoardPageId = "dd5cc0bb-91ff-81b9-8004-77df9cd3edb2";
test("Comment is shown with scroll and valid position", async ({ page }) => {
const viewer = new ViewerPage(page);
await viewer.setupLoggedInUser();
await viewer.setupFileWithComments();
await viewer.goToViewer({ fileId: singleBoardFileId, pageId: singleBoardPageId });
await viewer.goToViewer({
fileId: singleBoardFileId,
pageId: singleBoardPageId,
});
await viewer.showComments();
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(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.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.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");
});
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);
await workspacePage.setupEmptyFile();
await workspacePage.goToWorkspace();
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 }) => {
const workspacePage = new WorkspacePage(page);
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.rectShapeButton.click();
@ -42,8 +49,14 @@ test("User draws a rect", async ({ page }) => {
test("User makes a group", async ({ page }) => {
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-not-empty.json");
await workspacePage.mockRPC("update-file?id=*", "workspace/update-file-create-rect.json");
await workspacePage.mockRPC(
/get\-file\?/,
"workspace/get-file-not-empty.json",
);
await workspacePage.mockRPC(
"update-file?id=*",
"workspace/update-file-create-rect.json",
);
await workspacePage.goToWorkspace({
fileId: "6191cd35-bb1f-81f7-8004-7cc63d087374",
@ -54,7 +67,9 @@ test("User makes a group", async ({ page }) => {
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);
await workspacePage.setupEmptyFile();
await workspacePage.goToWorkspace();
@ -65,11 +80,19 @@ test("Bug 7654 - Toolbar keeps toggling on and off on spacebar press", async ({
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);
await workspacePage.setupEmptyFile();
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-not-empty.json");
await workspacePage.mockRPC("update-file?id=*", "workspace/update-file-create-rect.json");
await workspacePage.mockRPC(
/get\-file\?/,
"workspace/get-file-not-empty.json",
);
await workspacePage.mockRPC(
"update-file?id=*",
"workspace/update-file-create-rect.json",
);
await workspacePage.goToWorkspace({
fileId: "6191cd35-bb1f-81f7-8004-7cc63d087374",
@ -84,7 +107,7 @@ test("Bug 7525 - User moves a scrollbar and no selciont rectangle appears", asyn
await expect(horizontalScrollbar).toBeVisible();
// Grab scrollbar and move
const {x, y} = await horizontalScrollbar.boundingBox();
const { x, y } = await horizontalScrollbar.boundingBox();
await page.waitForTimeout(100);
await workspacePage.viewport.hover({ position: { x: x, y: y + 5 } });
await page.mouse.down();
@ -93,13 +116,24 @@ test("Bug 7525 - User moves a scrollbar and no selciont rectangle appears", asyn
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);
await workspacePage.setupEmptyFile();
await workspacePage.mockRPC("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("get-team-shared-files?team-id=*", "workspace/get-team-shared-libraries-non-empty.json");
await workspacePage.mockRPC(
"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(
"get-team-shared-files?team-id=*",
"workspace/get-team-shared-libraries-non-empty.json",
);
await workspacePage.goToWorkspace();
// Add Testing library 1
@ -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
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-library.json");
await workspacePage.openLibrariesModal();
await workspacePage.clickLibrary("Testing library 1")
await workspacePage.closeLibrariesModal();
await workspacePage.clickLibrary("Testing library 1");
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
await workspacePage.openLibrariesModal();
await workspacePage.clickLibrary("Testing library 1")
await workspacePage.clickLibrary("Testing library 1");
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);
await workspacePage.setupEmptyFile();
await workspacePage.goToWorkspace();
@ -129,5 +171,9 @@ test("Bug 7489 - Workspace-palette items stay hidden when opening with keyboard-
await workspacePage.clickTogglePalettesVisibility();
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 }) => {
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 }) => {
@ -123,7 +127,9 @@ test("User goes to a full search page", async ({ page }) => {
await dashboardPage.searchInput.fill("3");
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();
});
@ -157,7 +163,9 @@ test("User goes to password management section", async ({ page }) => {
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();
});

View file

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

View file

@ -9,15 +9,20 @@ const setupFileWithAssets = async (workspace) => {
const fileId = "015fda4f-caa6-8103-8004-862a00dd4f31";
const pageId = "015fda4f-caa6-8103-8004-862a00ddbe94";
const fragments = {
"015fda4f-caa6-8103-8004-862a9e4b4d4b": "assets/get-file-fragment-with-assets-components.json",
"015fda4f-caa6-8103-8004-862a9e4ad279": "assets/get-file-fragmnet-with-assets-page.json",
"015fda4f-caa6-8103-8004-862a9e4b4d4b":
"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.mockRPC(/get\-file\?/, "assets/get-file-with-assets.json");
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 };
@ -69,7 +74,10 @@ test.describe("Assets tab", () => {
test("Shows the libraries modal correctly", async ({ page }) => {
const workspace = new WorkspacePage(page);
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(
"get-team-shared-files?team-id=*",
"workspace/get-team-shared-libraries-non-empty.json",
@ -95,7 +103,9 @@ test.describe("Assets tab", () => {
await workspace.clickAssets();
await workspace.sidebar.getByRole("button", { name: "Components" }).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();
@ -114,11 +124,19 @@ test.describe("Palette", () => {
await expect(workspace.page).toHaveScreenshot();
await workspace.palette.getByRole("button", { name: "Typographies" }).click();
await expect(workspace.palette.getByText("Source Sans Pro Regular")).toBeVisible();
await workspace.palette
.getByRole("button", { name: "Typographies" })
.click();
await expect(
workspace.palette.getByText("Source Sans Pro Regular"),
).toBeVisible();
await expect(workspace.page).toHaveScreenshot();
await workspace.palette.getByRole("button", { name: "Color Palette" }).click();
await expect(workspace.palette.getByRole("button", { name: "#7798ff" })).toBeVisible();
await workspace.palette
.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;
};
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));
return files;
@ -232,7 +234,9 @@ async function readTranslations() {
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();
@ -291,15 +295,23 @@ async function generateSvgSprite(files, prefix) {
}
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 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 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() {
@ -310,15 +322,23 @@ async function generateTemplates() {
const manifest = await readShadowManifest();
let content;
const iconsSprite = await fs.readFile("resources/public/images/sprites/symbol/icons.svg", "utf8");
const cursorsSprite = await fs.readFile("resources/public/images/sprites/symbol/cursors.svg", "utf8");
const iconsSprite = await fs.readFile(
"resources/public/images/sprites/symbol/icons.svg",
"utf8",
);
const cursorsSprite = await fs.readFile(
"resources/public/images/sprites/symbol/cursors.svg",
"utf8",
);
const partials = {
"../public/images/sprites/symbol/icons.svg": iconsSprite,
"../public/images/sprites/symbol/cursors.svg": cursorsSprite,
};
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(
"resources/templates/index.mustache",
@ -411,7 +431,10 @@ export async function copyAssets() {
await syncDirs("resources/images/", "resources/public/images/");
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);
log.info("done: copy assets", `(${ppt(end)})`);

View file

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

View file

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

View file

@ -9,7 +9,10 @@ const port = 3000;
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.listen(port, () => {

View file

@ -1,26 +1,25 @@
const fs = require('fs').promises;
const fs = require("fs").promises;
const gt = require("gettext-parser");
const path = require('path');
const util = require('node:util');
const execFile = util.promisify(require('node:child_process').execFile);
const path = require("path");
const util = require("node:util");
const execFile = util.promisify(require("node:child_process").execFile);
async function processMsgId(msgId){
return execFile('grep', ['-r', '-o', msgId, './src'])
.catch(()=> { return msgId})
async function processMsgId(msgId) {
return execFile("grep", ["-r", "-o", msgId, "./src"]).catch(() => {
return msgId;
});
}
async function processFile(f) {
const content = await fs.readFile(f);
const data = gt.po.parse(content, "utf-8")
const translations = data.translations[''];
const data = gt.po.parse(content, "utf-8");
const translations = data.translations[""];
const badIds = [];
for (const property in translations) {
const data = await processMsgId(translations[property].msgid);
if (data!=null && data.stdout === undefined){
badIds.push(data)
if (data != null && data.stdout === undefined) {
badIds.push(data);
}
}
@ -28,63 +27,77 @@ async function processFile(f) {
}
async function cleanFile(f, badIds) {
console.log ("\n\nDoing automatic cleanup")
console.log("\n\nDoing automatic cleanup");
const content = await fs.readFile(f);
const data = gt.po.parse(content, "utf-8");
const translations = data.translations[''];
const translations = data.translations[""];
const keys = Object.keys(translations);
for (const key of keys) {
property = translations[key];
if (badIds.includes(property.msgid)){
console.log ('----> deleting', property.msgid)
delete data.translations[''][key];
if (badIds.includes(property.msgid)) {
console.log("----> deleting", property.msgid);
delete data.translations[""][key];
}
}
const buff = gt.po.compile(data, {sort: true});
const buff = gt.po.compile(data, { sort: true });
await fs.writeFile(f, buff);
}
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);
}
async function welcome() {
console.log ('####################################################################')
console.log ('# UNUSED TRANSLATIONS FINDER #')
console.log ('####################################################################')
console.log ('\n');
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 ('--------------------------------------------------------------------');
console.log(
"####################################################################",
);
console.log(
"# UNUSED TRANSLATIONS FINDER #",
);
console.log(
"####################################################################",
);
console.log("\n");
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();
console.log ('--------------------------------------------------------------------');
console.log(
"--------------------------------------------------------------------",
);
}
const doCleanup = process.argv.slice(2)[0] == "--clean";
;(async () => {
(async () => {
await welcome();
const target = path.normalize("./translations/en.po");
const badIds = await processFile(target);
if (doCleanup){
if (doCleanup) {
cleanFile(target, badIds);
} else {
for (const badId of badIds){
for (const badId of badIds) {
console.log(badId);
}
}
})()
})();

View file

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

View file

@ -11,7 +11,7 @@ let sass = null;
async function compileSassAll() {
const start = process.hrtime();
log.info("init: compile styles")
log.info("init: compile styles");
sass = await h.compileSassAll(worker);
let output = await h.concatSass(sass);
@ -24,7 +24,7 @@ async function compileSassAll() {
async function compileSass(path) {
const start = process.hrtime();
log.info("changed:", path);
const result = await h.compileSass(worker, path, {modules:true});
const result = await h.compileSass(worker, path, { modules: true });
sass.index[result.outputPath] = result.css;
const output = h.concatSass(sass);
@ -37,12 +37,12 @@ async function compileSass(path) {
await fs.mkdir("./resources/public/css/", { recursive: true });
await compileSassAll();
await h.copyAssets()
await h.compileSvgSprites()
await h.copyAssets();
await h.compileSvgSprites();
await h.compileTemplates();
await h.compilePolyfills();
log.info("watch: scss src (~)")
log.info("watch: scss src (~)");
h.watch("src", h.isSassFile, async function (path) {
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) {
log.info("changed:", path);
await compileSassAll()
await compileSassAll();
});
log.info("watch: templates (~)")
log.info("watch: templates (~)");
h.watch("resources/templates", null, async function (path) {
log.info("changed:", path);
await h.compileTemplates();
});
log.info("watch: translations (~)")
log.info("watch: translations (~)");
h.watch("translations", null, async function (path) {
log.info("changed:", path);
await h.compileTemplates();
});
log.info("watch: assets (~)")
h.watch(["resources/images", "resources/fonts", "resources/plugins-runtime"], null, async function (path) {
log.info("changed:", path);
await h.compileSvgSprites();
await h.copyAssets();
await h.compileTemplates();
});
log.info("watch: assets (~)");
h.watch(
["resources/images", "resources/fonts", "resources/plugins-runtime"],
null,
async function (path) {
log.info("changed:", path);
await h.compileSvgSprites();
await h.copyAssets();
await h.compileTemplates();
},
);
worker.terminate();

View file

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