mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-21 22:19:41 +01:00
fix: make sure all tests pass
This commit is contained in:
@@ -25,13 +25,12 @@ test("delete the last note of a color", async ({ page }) => {
|
||||
const noteSelector = await createNoteAndCheckPresence();
|
||||
|
||||
await useContextMenu(noteSelector, async () => {
|
||||
await clickMenuItem("colors-Red");
|
||||
await clickMenuItem("colors");
|
||||
await clickMenuItem("red");
|
||||
});
|
||||
|
||||
expect(await page.isVisible(new Menu("navitem").item("red").build())).toBe(
|
||||
true
|
||||
);
|
||||
await page.waitForTimeout(500);
|
||||
const navItem = new Menu("navitem").item("red").build();
|
||||
await page.waitForSelector(navItem);
|
||||
|
||||
await useContextMenu(noteSelector, async () => {
|
||||
await clickMenuItem("movetotrash");
|
||||
|
||||
@@ -207,7 +207,7 @@ test("select all & backspace should clear all content in editor", async () => {
|
||||
await expect(getEditorContent()).resolves.toBe("");
|
||||
});
|
||||
|
||||
test.only("last line doesn't get saved if it's font is different", async () => {
|
||||
test("last line doesn't get saved if it's font is different", async () => {
|
||||
const selector = await createNoteAndCheckPresence();
|
||||
|
||||
await page.keyboard.press("Enter");
|
||||
|
||||
@@ -10,7 +10,11 @@ const {
|
||||
} = require("./utils/actions");
|
||||
const List = require("./utils/listitemidbuilder");
|
||||
const Menu = require("./utils/menuitemidbuilder");
|
||||
const { checkNotePresence, isPresent } = require("./utils/conditions");
|
||||
const {
|
||||
checkNotePresence,
|
||||
isPresent,
|
||||
checkMenuItemText,
|
||||
} = require("./utils/conditions");
|
||||
|
||||
/**
|
||||
* @type {Page}
|
||||
@@ -203,7 +207,7 @@ test("permanently delete a notebook", async () => {
|
||||
).resolves.toBeFalsy();
|
||||
});
|
||||
|
||||
test("pin a notebook", async () => {
|
||||
test("pin a notebook", async ({ page }) => {
|
||||
const notebookSelector = await createNotebookAndCheckPresence();
|
||||
|
||||
await useContextMenu(notebookSelector, () => clickMenuItem("pin"));
|
||||
@@ -211,10 +215,9 @@ test("pin a notebook", async () => {
|
||||
// wait for the menu to properly close
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await useContextMenu(notebookSelector, () =>
|
||||
expect(
|
||||
isPresent(Menu.new("menuitem").item("unpin").build())
|
||||
).resolves.toBeTruthy()
|
||||
await useContextMenu(
|
||||
notebookSelector,
|
||||
async () => await checkMenuItemText("pin", "Unpin")
|
||||
);
|
||||
|
||||
// wait for the menu to properly close
|
||||
|
||||
@@ -30,6 +30,7 @@ const {
|
||||
isAbsent,
|
||||
checkNotePresence,
|
||||
createNoteAndCheckPresence,
|
||||
checkMenuItemText,
|
||||
} = require("./utils/conditions");
|
||||
const List = require("./utils/listitemidbuilder");
|
||||
const Menu = require("./utils/menuitemidbuilder");
|
||||
@@ -66,10 +67,10 @@ async function deleteNoteAndCheckAbsence(viewId = "home") {
|
||||
return trashItemSelector;
|
||||
}
|
||||
|
||||
async function lockUnlockNote(noteSelector, type) {
|
||||
async function lockUnlockNote(noteSelector) {
|
||||
await openContextMenu(noteSelector);
|
||||
|
||||
await clickMenuItem(type);
|
||||
await clickMenuItem("lock");
|
||||
|
||||
await page.fill(getTestId("dialog-password"), PASSWORD);
|
||||
|
||||
@@ -93,9 +94,7 @@ async function openLockedNote(noteSelector) {
|
||||
async function checkNotePinned(noteSelector, pause) {
|
||||
await openContextMenu(noteSelector);
|
||||
|
||||
const unpinSelector = Menu.new("menuitem").item("unpin").build();
|
||||
|
||||
await expect(isPresent(unpinSelector)).resolves.toBeTruthy();
|
||||
await checkMenuItemText("pin", "Unpin");
|
||||
|
||||
await closeContextMenu(noteSelector);
|
||||
|
||||
@@ -114,11 +113,11 @@ async function checkNoteLocked(noteSelector) {
|
||||
isAbsent(List.new("note").grouped().atIndex(0).body().build())
|
||||
).resolves.toBeTruthy();
|
||||
|
||||
await useContextMenu(noteSelector, () =>
|
||||
expect(
|
||||
isPresent(Menu.new("menuitem").item("unlock").build())
|
||||
).resolves.toBeTruthy()
|
||||
);
|
||||
await openContextMenu(noteSelector);
|
||||
|
||||
await checkMenuItemText("lock", "Unlock");
|
||||
|
||||
await closeContextMenu(noteSelector);
|
||||
}
|
||||
|
||||
async function checkNoteColored(noteSelector) {
|
||||
@@ -126,8 +125,10 @@ async function checkNoteColored(noteSelector) {
|
||||
|
||||
await openContextMenu(noteSelector);
|
||||
|
||||
await page.click(Menu.new("menuitem").item("colors").build());
|
||||
|
||||
await expect(
|
||||
isPresent(Menu.new("menuitem").colorCheck("Red").build())
|
||||
isPresent(Menu.new("menuitem").item("red").checked().build())
|
||||
).resolves.toBeTruthy();
|
||||
|
||||
await closeContextMenu(noteSelector);
|
||||
@@ -188,10 +189,7 @@ async function exportNote(format) {
|
||||
Date.prototype.toLocaleString = () => "xxx";
|
||||
});
|
||||
|
||||
const output = await downloadFile(
|
||||
getTestId(`export-dialog-${format}`),
|
||||
"utf-8"
|
||||
);
|
||||
const output = await downloadFile(getTestId(`menuitem-${format}`), "utf-8");
|
||||
expect(output).toMatchSnapshot(`export-${format}.txt`);
|
||||
}
|
||||
|
||||
@@ -230,7 +228,7 @@ test.describe("run tests independently", () => {
|
||||
|
||||
await openContextMenu(noteSelector);
|
||||
|
||||
await clickMenuItem("addtonotebook(s)");
|
||||
await clickMenuItem("addtonotebook");
|
||||
|
||||
await addNoteToNotebook();
|
||||
});
|
||||
@@ -242,11 +240,13 @@ test.describe("run tests independently", () => {
|
||||
await clickMenuItem("favorite");
|
||||
});
|
||||
|
||||
await useContextMenu(noteSelector, async () => {
|
||||
await expect(
|
||||
isPresent(Menu.new("menuitem").item("unfavorite").build())
|
||||
).resolves.toBeTruthy();
|
||||
});
|
||||
await useContextMenu(
|
||||
noteSelector,
|
||||
async () => {
|
||||
await checkMenuItemText("favorite", "Unfavorite");
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
await navigateTo("favorites");
|
||||
|
||||
@@ -265,14 +265,16 @@ test.describe("run tests independently", () => {
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await useContextMenu(noteSelector, async () => {
|
||||
await clickMenuItem("unfavorite");
|
||||
await clickMenuItem("favorite");
|
||||
});
|
||||
|
||||
await useContextMenu(noteSelector, async () => {
|
||||
await expect(
|
||||
isPresent(Menu.new("menuitem").item("favorite").build())
|
||||
).resolves.toBeTruthy();
|
||||
});
|
||||
await useContextMenu(
|
||||
noteSelector,
|
||||
async () => {
|
||||
await checkMenuItemText("favorite", "Favorite");
|
||||
},
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
test("favorite a note from properties", async () => {
|
||||
@@ -288,11 +290,13 @@ test.describe("run tests independently", () => {
|
||||
|
||||
noteSelector = await checkNotePresence("notes");
|
||||
|
||||
await useContextMenu(noteSelector, async () => {
|
||||
await expect(
|
||||
isPresent(Menu.new("menuitem").item("unfavorite").build())
|
||||
).resolves.toBeTruthy();
|
||||
});
|
||||
await useContextMenu(
|
||||
noteSelector,
|
||||
async () => {
|
||||
await checkMenuItemText("favorite", "Unfavorite");
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
await navigateTo("notes");
|
||||
});
|
||||
@@ -302,7 +306,8 @@ test.describe("run tests independently", () => {
|
||||
|
||||
await openContextMenu(noteSelector);
|
||||
|
||||
await page.click(Menu.new("menuitem").color("Red").build());
|
||||
await page.click(Menu.new("menuitem").item("colors").build());
|
||||
await page.click(Menu.new("menuitem").item("red").build());
|
||||
|
||||
await page.click(getTestId("properties"));
|
||||
|
||||
@@ -330,12 +335,12 @@ test.describe("run tests independently", () => {
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await useContextMenu(noteSelector, () => clickMenuItem("unpin"));
|
||||
await useContextMenu(noteSelector, () => clickMenuItem("pin"));
|
||||
|
||||
await useContextMenu(noteSelector, () =>
|
||||
expect(
|
||||
isPresent(Menu.new("menuitem").item("pin").build())
|
||||
).resolves.toBeTruthy()
|
||||
await useContextMenu(
|
||||
noteSelector,
|
||||
async () => await checkMenuItemText("pin", "Pin"),
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
@@ -369,7 +374,7 @@ test.describe("run tests independently", () => {
|
||||
test("lock a note", async () => {
|
||||
const noteSelector = await createNoteAndCheckPresence();
|
||||
|
||||
await lockUnlockNote(noteSelector, "lock");
|
||||
await lockUnlockNote(noteSelector);
|
||||
|
||||
await checkNoteLocked(noteSelector);
|
||||
});
|
||||
@@ -393,9 +398,7 @@ test.describe("run tests independently", () => {
|
||||
|
||||
await openContextMenu(noteSelector);
|
||||
|
||||
await expect(
|
||||
isPresent(Menu.new("menuitem").item("lock").build())
|
||||
).resolves.toBeTruthy();
|
||||
await checkMenuItemText("lock", "Lock");
|
||||
|
||||
await closeContextMenu(noteSelector);
|
||||
});
|
||||
|
||||
@@ -67,7 +67,7 @@ async function createTagAndCheckPresence(title) {
|
||||
|
||||
async function renameTag(tagSelector, newTitle, expected) {
|
||||
await useContextMenu(tagSelector.build(), async () => {
|
||||
await clickMenuItem("renametag");
|
||||
await clickMenuItem("rename");
|
||||
});
|
||||
|
||||
await page.fill(getTestId("item-dialog-title"), newTitle);
|
||||
@@ -167,7 +167,7 @@ test("create a shortcut of a tag", async ({ page }) => {
|
||||
const tagSelector = await createTagAndCheckPresence("helloworld");
|
||||
|
||||
await useContextMenu(tagSelector.build(), async () => {
|
||||
await clickMenuItem("createshortcut");
|
||||
await clickMenuItem("shortcut");
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -183,7 +183,7 @@ test("delete a shortcut of a tag", async ({ page }) => {
|
||||
const tagSelector = await createTagAndCheckPresence("helloworld");
|
||||
|
||||
await useContextMenu(tagSelector.build(), async () => {
|
||||
await clickMenuItem("createshortcut");
|
||||
await clickMenuItem("shortcut");
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -208,7 +208,7 @@ test("delete the last note of a tag that is also a shortcut", async ({
|
||||
const tagSelector = await createTagAndCheckPresence("helloworld");
|
||||
|
||||
await useContextMenu(tagSelector.build(), async () => {
|
||||
await clickMenuItem("createshortcut");
|
||||
await clickMenuItem("shortcut");
|
||||
});
|
||||
|
||||
await page.click(tagSelector.build());
|
||||
|
||||
@@ -18,15 +18,15 @@ async function openContextMenu(selector) {
|
||||
}
|
||||
|
||||
async function closeContextMenu() {
|
||||
await page.click("body", { button: "left" });
|
||||
await page.keyboard.press("Escape");
|
||||
}
|
||||
|
||||
async function useContextMenu(selector, action) {
|
||||
async function useContextMenu(selector, action, close = false) {
|
||||
await openContextMenu(selector);
|
||||
|
||||
await action();
|
||||
|
||||
await closeContextMenu();
|
||||
if (close) await closeContextMenu();
|
||||
}
|
||||
|
||||
async function confirmDialog() {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
const { expect } = require("@playwright/test");
|
||||
const { getTestId, NOTE, createNote } = require(".");
|
||||
const List = require("./listitemidbuilder");
|
||||
const Menu = require("./menuitemidbuilder");
|
||||
|
||||
async function isPresent(selector) {
|
||||
try {
|
||||
@@ -59,10 +60,17 @@ async function createNoteAndCheckPresence(
|
||||
return noteSelector;
|
||||
}
|
||||
|
||||
async function checkMenuItemText(itemId, expectedText) {
|
||||
await expect(
|
||||
page.textContent(Menu.new("menuitem").item(itemId).build())
|
||||
).resolves.toBe(expectedText);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isPresent,
|
||||
isAbsent,
|
||||
isToastPresent,
|
||||
checkNotePresence,
|
||||
createNoteAndCheckPresence,
|
||||
checkMenuItemText,
|
||||
};
|
||||
|
||||
@@ -71,7 +71,7 @@ async function downloadFile(downloadActionSelector, encoding) {
|
||||
return new Promise(async (resolve) => {
|
||||
page.on("download", async (download) => {
|
||||
const path = await download.path();
|
||||
resolve(fs.readFileSync(path, { encoding }).toString());
|
||||
resolve(fs.readFileSync(path, { encoding }));
|
||||
});
|
||||
await page.waitForSelector(downloadActionSelector);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ class MenuItemIDBuilder {
|
||||
}
|
||||
constructor(type) {
|
||||
this.type = type;
|
||||
this.suffix = "";
|
||||
}
|
||||
|
||||
item(itemId) {
|
||||
@@ -13,18 +14,15 @@ class MenuItemIDBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
colorCheck(color) {
|
||||
this.itemId = "colors-" + color + "-check";
|
||||
return this;
|
||||
}
|
||||
|
||||
color(color) {
|
||||
this.itemId = "colors-" + color;
|
||||
checked() {
|
||||
this.suffix = "checked";
|
||||
return this;
|
||||
}
|
||||
|
||||
build() {
|
||||
return getTestId(`${this.type}-${this.itemId}`);
|
||||
return getTestId(
|
||||
`${this.type}-${this.itemId}${this.suffix ? `-${this.suffix}` : ""}`
|
||||
);
|
||||
}
|
||||
}
|
||||
module.exports = MenuItemIDBuilder;
|
||||
|
||||
@@ -42,9 +42,9 @@ module.exports = {
|
||||
timeout: 30000,
|
||||
workers: IS_CI ? 3 : 4,
|
||||
reporter: "list",
|
||||
retries: IS_CI ? 3 : 1,
|
||||
retries: IS_CI ? 3 : 0,
|
||||
use: {
|
||||
headless: false,
|
||||
headless: true,
|
||||
acceptDownloads: true,
|
||||
|
||||
// Artifacts
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
import { removeStatus, updateStatus } from "../hooks/use-status";
|
||||
import {
|
||||
showMultiDeleteConfirmation,
|
||||
showMultiPermanentDeleteConfirmation,
|
||||
} from "./dialog-controller";
|
||||
import { store as editorStore } from "../stores/editor-store";
|
||||
import { store as appStore } from "../stores/app-store";
|
||||
import { showMultiDeleteConfirmation } from "./dialog-controller";
|
||||
import { store as noteStore } from "../stores/note-store";
|
||||
import { store as notebookStore } from "../stores/notebook-store";
|
||||
import { db } from "./db";
|
||||
import { hashNavigate } from "../navigation";
|
||||
import { showToast } from "../utils/toast";
|
||||
import Vault from "./vault";
|
||||
import { showItemDeletedToast } from "./toasts";
|
||||
import { TaskManager } from "./task-manager";
|
||||
|
||||
async function moveNotesToTrash(notes: any[]) {
|
||||
console.log(notes);
|
||||
|
||||
const item = notes[0];
|
||||
const isMultiselect = notes.length > 1;
|
||||
if (isMultiselect) {
|
||||
|
||||
@@ -68,12 +68,12 @@ function ListItem(props) {
|
||||
let title = props.item.title;
|
||||
let selectedItems = selectionStore.get().selectedItems.slice();
|
||||
|
||||
if (isSelected || isFocused) {
|
||||
if (isSelected) {
|
||||
title = `${selectedItems.length} items selected`;
|
||||
items = items.filter((item) => item.multiSelect);
|
||||
} else if (Config.get("debugMode", false)) {
|
||||
items.push(...debugMenuItems(props.item.type));
|
||||
} else {
|
||||
} else if (selectedItems.indexOf(props.item) === -1) {
|
||||
selectedItems.push(props.item);
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,10 @@ function Menu({ items, data, title, closeMenu }) {
|
||||
key={item.key}
|
||||
index={index}
|
||||
item={item}
|
||||
onClick={(e) => onAction(e, item)}
|
||||
onClick={(e) => {
|
||||
if (item.items?.length) setIsSubmenuOpen(true);
|
||||
else onAction(e, item);
|
||||
}}
|
||||
isFocused={focusIndex === index}
|
||||
onHover={() => {
|
||||
setFocusIndex(index);
|
||||
|
||||
@@ -35,7 +35,7 @@ function MenuItem({ item, isFocused, onHover, onClick }) {
|
||||
<Flex as="li" flexDirection={"column"} flex={1} onMouseOver={onHover}>
|
||||
<Button
|
||||
id={key}
|
||||
data-test-id={`menuitem-${title.split(" ").join("").toLowerCase()}`}
|
||||
data-test-id={`menuitem-${key}`}
|
||||
key={key}
|
||||
ref={itemRef}
|
||||
tabIndex={-1}
|
||||
@@ -65,7 +65,9 @@ function MenuItem({ item, isFocused, onHover, onClick }) {
|
||||
{isPremium && <Pro size={14} color="primary" sx={{ ml: 1 }} />}
|
||||
</Flex>
|
||||
<Flex>
|
||||
{isChecked && <Check size={14} />}
|
||||
{isChecked && (
|
||||
<Check size={14} data-test-id={`menuitem-${key}-checked`} />
|
||||
)}
|
||||
{hasSubmenu && <ChevronRight size={14} />}
|
||||
{modifier && (
|
||||
<Text
|
||||
|
||||
@@ -251,19 +251,7 @@ const menuItems = [
|
||||
key: "colors",
|
||||
title: "Assign color",
|
||||
icon: Icon.Colors,
|
||||
items: COLORS.map((label) => ({
|
||||
key: label,
|
||||
title: db.colors.alias(label.toLowerCase()) || label.toLowerCase(),
|
||||
icon: Icon.Circle,
|
||||
iconColor: label.toLowerCase(),
|
||||
checked: ({ note }) => {
|
||||
return note.color === label.toLowerCase();
|
||||
},
|
||||
onClick: ({ note }) => {
|
||||
const { id } = note;
|
||||
store.setColor(id, label.toLowerCase());
|
||||
},
|
||||
})),
|
||||
items: colorsToMenuItems(),
|
||||
},
|
||||
{
|
||||
key: "publish",
|
||||
@@ -300,7 +288,7 @@ const menuItems = [
|
||||
isPro: true,
|
||||
},
|
||||
{
|
||||
key: "unlocknote",
|
||||
key: "lock",
|
||||
title: ({ note }) => (note.locked ? "Unlock" : "Lock"),
|
||||
icon: Icon.Lock,
|
||||
onClick: async ({ note }) => {
|
||||
@@ -349,3 +337,22 @@ const topicNoteMenuItems = [
|
||||
multiSelect: true,
|
||||
},
|
||||
];
|
||||
|
||||
function colorsToMenuItems() {
|
||||
return COLORS.map((label) => {
|
||||
label = label.toLowerCase();
|
||||
return {
|
||||
key: label,
|
||||
title: db.colors.alias(label) || label,
|
||||
icon: Icon.Circle,
|
||||
iconColor: label,
|
||||
checked: ({ note }) => {
|
||||
return note.color === label;
|
||||
},
|
||||
onClick: ({ note }) => {
|
||||
const { id } = note;
|
||||
store.setColor(id, label);
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -105,12 +105,13 @@ const pin = (notebook) => {
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
key: "edit",
|
||||
title: "Edit",
|
||||
icon: Icon.NotebookEdit,
|
||||
onClick: ({ notebook }) => hashNavigate(`/notebooks/${notebook.id}/edit`),
|
||||
},
|
||||
{
|
||||
key: "pinnotebook",
|
||||
key: "pin",
|
||||
icon: Icon.Pin,
|
||||
title: ({ notebook }) => (notebook.pinned ? "Unpin" : "Pin"),
|
||||
onClick: ({ notebook }) => pin(notebook),
|
||||
@@ -123,6 +124,7 @@ const menuItems = [
|
||||
onClick: ({ notebook }) => appStore.pinItemToMenu(notebook),
|
||||
},
|
||||
{
|
||||
key: "movetotrash",
|
||||
title: "Move to trash",
|
||||
color: "error",
|
||||
iconColor: "error",
|
||||
|
||||
@@ -11,6 +11,7 @@ import { showToast } from "../../utils/toast";
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
key: "rename",
|
||||
title: "Rename tag",
|
||||
icon: Icon.Edit,
|
||||
onClick: ({ tag }) => {
|
||||
@@ -18,12 +19,14 @@ const menuItems = [
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "shortcut",
|
||||
title: ({ tag }) =>
|
||||
db.settings.isPinned(tag.id) ? "Remove shortcut" : "Create shortcut",
|
||||
icon: Icon.Shortcut,
|
||||
onClick: ({ tag }) => appStore.pinItemToMenu(tag),
|
||||
},
|
||||
{
|
||||
key: "delete",
|
||||
color: "error",
|
||||
iconColor: "error",
|
||||
title: "Delete",
|
||||
|
||||
@@ -34,6 +34,7 @@ export default TrashItem;
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
key: "restore",
|
||||
title: "Restore",
|
||||
icon: Icon.Restore,
|
||||
onClick: ({ items }) => {
|
||||
@@ -43,6 +44,7 @@ const menuItems = [
|
||||
multiSelect: true,
|
||||
},
|
||||
{
|
||||
key: "delete",
|
||||
title: "Delete",
|
||||
icon: Icon.DeleteForver,
|
||||
color: "error",
|
||||
|
||||
Reference in New Issue
Block a user