Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature - Remove standalone mods phase 5 - slices 1+2 #9123

Closed
wants to merge 55 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
d87f5a5
when saving mod, if inner id, show create mod modal, and remove save …
Sep 7, 2024
8675fa3
rename reset to clear changes
Sep 7, 2024
a1277bb
add test
Sep 7, 2024
543fe0f
rename component
Sep 7, 2024
2dbbbf7
change label
Sep 7, 2024
dd7a025
implement save logic for unsaved, temp mods
Sep 7, 2024
f48bbe7
fix save mod test
Sep 8, 2024
fb9e705
fix tests
Sep 9, 2024
45f85b1
make source parts required
Sep 9, 2024
6775e9f
undo input changes
Sep 9, 2024
61432f3
fix action menus and cleanup dead code
Sep 13, 2024
5598eca
cleanup
Sep 13, 2024
7da562d
Merge branch 'main' into feature/remove-standalone-mods-phase-5
Sep 13, 2024
aecc803
fix tests and restore saveasnewmodmodal
Sep 13, 2024
6ac0195
fix remaining tests
Sep 13, 2024
b114821
fix dead code
Sep 13, 2024
c441731
more dead code cleanup
Sep 13, 2024
b33eab7
add more timeout to activation spec
Sep 13, 2024
f54bf48
fix tests
Sep 16, 2024
dd8c519
fix mod lifecycle tests
Sep 16, 2024
87de61b
fix add new mod with starter bricks tests
Sep 16, 2024
c168125
fix starter brick spec, tests, update snapshots
Sep 16, 2024
3401671
fix brickActions test
Sep 16, 2024
7a4799a
fix brickConfiguration test
Sep 16, 2024
d7f5943
fix saveMod test
Sep 16, 2024
33762b8
fix doNotCloseSidebarOnSave regression test
Sep 16, 2024
66111eb
add snapshot
Sep 16, 2024
bec1f00
Merge branch 'main' into feature/remove-standalone-mods-phase-5
Sep 16, 2024
3189624
update action disabled and icons
Sep 16, 2024
6c0dab6
refactor mod listing panel sub components and implement some of the s…
Sep 17, 2024
5f8f959
some PR feedback and comment fixes
Sep 17, 2024
399402e
pr feedback and fix filter
Sep 17, 2024
bae2617
some more pr feedback fixes
Sep 17, 2024
c0130e1
fix filter tests and make create modal more clear
Sep 17, 2024
c540f3d
fix dead code
Sep 17, 2024
4e00e76
wip playwright tests modActions, some PR feedback
Sep 17, 2024
82e438a
Merge branch 'main' into feature/remove-standalone-mods-phase-5
Sep 17, 2024
5f9dcaf
first mod actions test passing
Sep 18, 2024
f241aec
add snapshots and more test fixes for saved mod actions
Sep 18, 2024
1ace8dd
Merge branch 'main' into feature/remove-standalone-mods-phase-5
Sep 18, 2024
c5b983c
add modUuid to saveMod to prevent test collision
mnholtz Sep 18, 2024
6eef444
show save button on all mods
Sep 19, 2024
c5ff334
fix 'add starter brick to mod' test
mnholtz Sep 19, 2024
038569b
fix editorStorage tests
grahamlangford Sep 19, 2024
903c7fa
fix deactivateModComponent tests
grahamlangford Sep 19, 2024
b1ac39c
avoid duplicated mod name for new mod when moving mod component
mnholtz Sep 19, 2024
fd06ccf
rename factory
grahamlangford Sep 20, 2024
7e556c0
Improve typing for api paths and update playwright documentation (#9167)
fungairino Sep 18, 2024
b117ee1
* Fix EllipsisMenu wrapping to next line
johnnymetz Sep 19, 2024
4abbbcb
9169 indexeddb logging disable flag + more debug logging (#9174)
fungairino Sep 19, 2024
847b427
Rename Organizations to Teams in the data model (#9170)
grahamlangford Sep 19, 2024
6525803
9169 idb log durability and timeout changes (#9177)
fungairino Sep 19, 2024
1f234ce
fix snapshots
grahamlangford Sep 20, 2024
10c511f
update snapshots
grahamlangford Sep 20, 2024
e4f66ec
merge main
grahamlangford Sep 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ export class EditWorkshopModPage extends BasePageObject {
await expect(
this.page.getByRole("status").filter({ hasText: "Deleted " }),
).toBeVisible();
await expect(this.page.getByRole("status")).toBeHidden();
mnholtz marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ export class WorkshopPage extends BasePageObject {

async findAndSelectMod(modId: string) {
await this.getByPlaceholder("Start typing to find results").fill(modId);
await this.getByRole("cell", { name: modId }).click();
const cellLocator = this.getByRole("cell", { name: modId });
await cellLocator.waitFor({ state: "visible", timeout: 5000 });
await cellLocator.click();

const editPage = new EditWorkshopModPage(this.page);
await editPage.editor.waitForLoad();
Expand Down
12 changes: 10 additions & 2 deletions end-to-end-tests/pageObjects/pageEditor/brickActionsPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import { BasePageObject } from "../basePageObject";
import { ModifiesModFormState } from "./utils";
import { expect } from "@playwright/test";

export class Brick extends BasePageObject {
moveBrickUpButton = this.getByRole("button", { name: "Move brick higher" });
Expand All @@ -40,7 +41,10 @@ export class Brick extends BasePageObject {
export class BrickActionsPanel extends BasePageObject {
removeBrickButton = this.getByTestId("icon-button-removeNode");
copyBrickButton = this.getByTestId("icon-button-copyNode");
bricks = this.getByTestId("editor-node");

get bricks() {
return this.getByTestId("editor-node");
}

getAddBrickButton(n: number) {
return this.getByTestId(/icon-button-.*-add-brick/).nth(n);
Expand Down Expand Up @@ -86,7 +90,11 @@ export class BrickActionsPanel extends BasePageObject {

// Add brick modal
await this.page.getByTestId("tag-search-input").fill(brickName);
await this.page.getByRole("button", { name: brickName }).first().click();
const brickResult = this.page
.getByRole("button", { name: brickName })
.first();
await expect(brickResult).toBeVisible();
await brickResult.click();

await this.page.getByRole("button", { name: "Add brick" }).click();
}
Expand Down
76 changes: 76 additions & 0 deletions end-to-end-tests/pageObjects/pageEditor/modActionMenu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (C) 2024 PixieBrix, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { BasePageObject } from "../basePageObject";
import { ModifiesModFormState } from "./utils";
import type { StarterBrickUIName } from "./types";
import { uuidv4 } from "@/types/helpers";
import { ConfigurationForm } from "./configurationForm";

class BaseActionMenu extends BasePageObject {
get clearOption() {
return this.page.getByRole("menuitem", { name: "Clear Changes" });
}
}

export class ModActionMenu extends BaseActionMenu {
@ModifiesModFormState
async addStarterBrick(starterBrickName: StarterBrickUIName): Promise<string> {
const uniqueBrickName = `${starterBrickName} ${uuidv4()}`;
await this.page
.getByRole("menuitem", { name: /Add Starter Brick/ })
.hover();
await this.page.getByRole("menuitem", { name: starterBrickName }).click();

const brickConfigurationPanel = new ConfigurationForm(
this.page.getByTestId("brickConfigurationPanel"),
);
await brickConfigurationPanel.fillField("name", uniqueBrickName);
await brickConfigurationPanel.waitForModFormStateToUpdate();
return uniqueBrickName;
}

get copyOption() {
return this.page.getByRole("menuitem", { name: "Make a copy" });
}

get deactivateOption() {
return this.page.getByRole("menuitem", { name: "Deactivate" });
}

get deleteNewModOption() {
return this.page.getByRole("menuitem", { name: "Delete new Mod" });
}
}

export class ModComponentActionMenu extends BaseActionMenu {
get duplicateOption() {
return this.page.getByRole("menuitem", { name: "Duplicate" });
}

get moveFromModOption() {
return this.page.getByRole("menuitem", { name: "Move from Mod" });
}

get copyToModOption() {
return this.page.getByRole("menuitem", { name: "Copy to Mod" });
}

get deleteOption() {
return this.page.getByRole("menuitem", { name: "Delete component" });
}
}
59 changes: 59 additions & 0 deletions end-to-end-tests/pageObjects/pageEditor/modListItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2024 PixieBrix, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { BasePageObject } from "../basePageObject";
import { ModActionMenu, ModComponentActionMenu } from "./modActionMenu";

class BaseListItem extends BasePageObject {
get dirtyIcon() {
return this.locator("span[title='Unsaved changes']");
}

get menuButton() {
return this.getByLabel(" - Ellipsis");
}

async select() {
return this.click({ timeout: 5000 });
}
}

export class ModListItem extends BaseListItem {
get saveButton() {
return this.locator("[data-icon=save]");
}

get modActionMenu() {
return new ModActionMenu(
this.locator("[data-testid='ellipsis-menu-button']"),
);
}
}

export class ModComponentListItem extends BaseListItem {
get unavailableIcon() {
return this.getByRole("img", {
name: "Not available on page",
});
}

get modComponentActionMenu() {
return new ModComponentActionMenu(
this.locator("[data-testid='ellipsis-menu-button']"),
);
}
}
84 changes: 11 additions & 73 deletions end-to-end-tests/pageObjects/pageEditor/modListingPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,82 +16,13 @@
*/

import { BasePageObject } from "../basePageObject";
import { uuidv4 } from "@/types/helpers";
import { ModifiesModFormState } from "./utils";

export type StarterBrickUIName =
| "Context Menu"
| "Trigger"
| "Button"
| "Quick Bar Action"
| "Dynamic Quick Bar"
| "Sidebar Panel";

export class ModActionMenu extends BasePageObject {
get copyButton() {
return this.getByRole("menuitem", { name: "Make a copy" });
}

get deactivateButton() {
return this.getByRole("menuitem", { name: "Deactivate" });
}

@ModifiesModFormState
async addStarterBrick(starterBrickName: StarterBrickUIName) {
await this.getByRole("menuitem", { name: "Add starter brick" }).hover();
await this.getByRole("menuitem", { name: starterBrickName }).click();
}
}

export class ModListItem extends BasePageObject {
saveButton = this.locator("[data-icon=save]");
get menuButton() {
return this.getByLabel(" - Ellipsis");
}

get unavailableIcon() {
return this.getByRole("img", {
name: "Not available on page",
});
}

async select() {
return this.click();
}

get modActionMenu() {
return new ModActionMenu(this.page.getByLabel("Menu"));
}
}
import { ModComponentListItem, ModListItem } from "./modListItem";

export class ModListingPanel extends BasePageObject {
addButton = this.getByRole("button", { name: "Add", exact: true });
newModButton = this.getByRole("button", { name: "New Mod", exact: true });
quickFilterInput = this.getByPlaceholder("Quick filter");
get activeModListItem() {
return new ModListItem(this.locator(".list-group-item.active"));
}

/**
* Adds a starter brick in the Page Editor. Generates a unique mod name to prevent
* test collision.
*
* @param starterBrickName the starter brick name to add, corresponding to the name shown in the Page Editor UI,
* not the underlying type
* @returns modName the generated mod name
*/
@ModifiesModFormState
async addStarterBrick(starterBrickName: StarterBrickUIName) {
const modUuid = uuidv4();
const modComponentName = `Test ${starterBrickName} ${modUuid}`;
await this.addButton.click();
await this.locator("[role=button].dropdown-item", {
hasText: starterBrickName,
}).click();

return { modComponentName, modUuid };
}

getModListItemByName(modName: string) {
getModListItemByName(modName: string | RegExp): ModListItem {
return new ModListItem(
this.locator(".list-group-item", { hasText: modName }).first(),
);
Expand All @@ -101,12 +32,19 @@ export class ModListingPanel extends BasePageObject {
const modStarterBricks = this.locator(
`.collapse:below(:text("${modName}"))`,
);
return new ModListItem(
return new ModComponentListItem(
modStarterBricks
.locator(".list-group-item", {
hasText: starterBrickName,
})
.first(),
);
}

getAllModStarterBricks(modName: string) {
const modStarterBricks = this.locator(
`.collapse:below(:text("${modName}"))`,
);
return modStarterBricks.locator(".list-group-item");
}
}
Loading
Loading