fix: make sure all tests pass

This commit is contained in:
thecodrr
2022-02-15 10:21:52 +05:00
parent f449fb6c33
commit 111ffa94ce
18 changed files with 125 additions and 100 deletions

View File

@@ -25,13 +25,12 @@ test("delete the last note of a color", async ({ page }) => {
const noteSelector = await createNoteAndCheckPresence(); const noteSelector = await createNoteAndCheckPresence();
await useContextMenu(noteSelector, async () => { 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( const navItem = new Menu("navitem").item("red").build();
true await page.waitForSelector(navItem);
);
await page.waitForTimeout(500);
await useContextMenu(noteSelector, async () => { await useContextMenu(noteSelector, async () => {
await clickMenuItem("movetotrash"); await clickMenuItem("movetotrash");

View File

@@ -207,7 +207,7 @@ test("select all & backspace should clear all content in editor", async () => {
await expect(getEditorContent()).resolves.toBe(""); 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(); const selector = await createNoteAndCheckPresence();
await page.keyboard.press("Enter"); await page.keyboard.press("Enter");

View File

@@ -10,7 +10,11 @@ const {
} = require("./utils/actions"); } = require("./utils/actions");
const List = require("./utils/listitemidbuilder"); const List = require("./utils/listitemidbuilder");
const Menu = require("./utils/menuitemidbuilder"); const Menu = require("./utils/menuitemidbuilder");
const { checkNotePresence, isPresent } = require("./utils/conditions"); const {
checkNotePresence,
isPresent,
checkMenuItemText,
} = require("./utils/conditions");
/** /**
* @type {Page} * @type {Page}
@@ -203,7 +207,7 @@ test("permanently delete a notebook", async () => {
).resolves.toBeFalsy(); ).resolves.toBeFalsy();
}); });
test("pin a notebook", async () => { test("pin a notebook", async ({ page }) => {
const notebookSelector = await createNotebookAndCheckPresence(); const notebookSelector = await createNotebookAndCheckPresence();
await useContextMenu(notebookSelector, () => clickMenuItem("pin")); await useContextMenu(notebookSelector, () => clickMenuItem("pin"));
@@ -211,10 +215,9 @@ test("pin a notebook", async () => {
// wait for the menu to properly close // wait for the menu to properly close
await page.waitForTimeout(500); await page.waitForTimeout(500);
await useContextMenu(notebookSelector, () => await useContextMenu(
expect( notebookSelector,
isPresent(Menu.new("menuitem").item("unpin").build()) async () => await checkMenuItemText("pin", "Unpin")
).resolves.toBeTruthy()
); );
// wait for the menu to properly close // wait for the menu to properly close

View File

@@ -30,6 +30,7 @@ const {
isAbsent, isAbsent,
checkNotePresence, checkNotePresence,
createNoteAndCheckPresence, createNoteAndCheckPresence,
checkMenuItemText,
} = require("./utils/conditions"); } = require("./utils/conditions");
const List = require("./utils/listitemidbuilder"); const List = require("./utils/listitemidbuilder");
const Menu = require("./utils/menuitemidbuilder"); const Menu = require("./utils/menuitemidbuilder");
@@ -66,10 +67,10 @@ async function deleteNoteAndCheckAbsence(viewId = "home") {
return trashItemSelector; return trashItemSelector;
} }
async function lockUnlockNote(noteSelector, type) { async function lockUnlockNote(noteSelector) {
await openContextMenu(noteSelector); await openContextMenu(noteSelector);
await clickMenuItem(type); await clickMenuItem("lock");
await page.fill(getTestId("dialog-password"), PASSWORD); await page.fill(getTestId("dialog-password"), PASSWORD);
@@ -93,9 +94,7 @@ async function openLockedNote(noteSelector) {
async function checkNotePinned(noteSelector, pause) { async function checkNotePinned(noteSelector, pause) {
await openContextMenu(noteSelector); await openContextMenu(noteSelector);
const unpinSelector = Menu.new("menuitem").item("unpin").build(); await checkMenuItemText("pin", "Unpin");
await expect(isPresent(unpinSelector)).resolves.toBeTruthy();
await closeContextMenu(noteSelector); await closeContextMenu(noteSelector);
@@ -114,11 +113,11 @@ async function checkNoteLocked(noteSelector) {
isAbsent(List.new("note").grouped().atIndex(0).body().build()) isAbsent(List.new("note").grouped().atIndex(0).body().build())
).resolves.toBeTruthy(); ).resolves.toBeTruthy();
await useContextMenu(noteSelector, () => await openContextMenu(noteSelector);
expect(
isPresent(Menu.new("menuitem").item("unlock").build()) await checkMenuItemText("lock", "Unlock");
).resolves.toBeTruthy()
); await closeContextMenu(noteSelector);
} }
async function checkNoteColored(noteSelector) { async function checkNoteColored(noteSelector) {
@@ -126,8 +125,10 @@ async function checkNoteColored(noteSelector) {
await openContextMenu(noteSelector); await openContextMenu(noteSelector);
await page.click(Menu.new("menuitem").item("colors").build());
await expect( await expect(
isPresent(Menu.new("menuitem").colorCheck("Red").build()) isPresent(Menu.new("menuitem").item("red").checked().build())
).resolves.toBeTruthy(); ).resolves.toBeTruthy();
await closeContextMenu(noteSelector); await closeContextMenu(noteSelector);
@@ -188,10 +189,7 @@ async function exportNote(format) {
Date.prototype.toLocaleString = () => "xxx"; Date.prototype.toLocaleString = () => "xxx";
}); });
const output = await downloadFile( const output = await downloadFile(getTestId(`menuitem-${format}`), "utf-8");
getTestId(`export-dialog-${format}`),
"utf-8"
);
expect(output).toMatchSnapshot(`export-${format}.txt`); expect(output).toMatchSnapshot(`export-${format}.txt`);
} }
@@ -230,7 +228,7 @@ test.describe("run tests independently", () => {
await openContextMenu(noteSelector); await openContextMenu(noteSelector);
await clickMenuItem("addtonotebook(s)"); await clickMenuItem("addtonotebook");
await addNoteToNotebook(); await addNoteToNotebook();
}); });
@@ -242,11 +240,13 @@ test.describe("run tests independently", () => {
await clickMenuItem("favorite"); await clickMenuItem("favorite");
}); });
await useContextMenu(noteSelector, async () => { await useContextMenu(
await expect( noteSelector,
isPresent(Menu.new("menuitem").item("unfavorite").build()) async () => {
).resolves.toBeTruthy(); await checkMenuItemText("favorite", "Unfavorite");
}); },
true
);
await navigateTo("favorites"); await navigateTo("favorites");
@@ -265,14 +265,16 @@ test.describe("run tests independently", () => {
await page.waitForTimeout(500); await page.waitForTimeout(500);
await useContextMenu(noteSelector, async () => { await useContextMenu(noteSelector, async () => {
await clickMenuItem("unfavorite"); await clickMenuItem("favorite");
}); });
await useContextMenu(noteSelector, async () => { await useContextMenu(
await expect( noteSelector,
isPresent(Menu.new("menuitem").item("favorite").build()) async () => {
).resolves.toBeTruthy(); await checkMenuItemText("favorite", "Favorite");
}); },
true
);
}); });
test("favorite a note from properties", async () => { test("favorite a note from properties", async () => {
@@ -288,11 +290,13 @@ test.describe("run tests independently", () => {
noteSelector = await checkNotePresence("notes"); noteSelector = await checkNotePresence("notes");
await useContextMenu(noteSelector, async () => { await useContextMenu(
await expect( noteSelector,
isPresent(Menu.new("menuitem").item("unfavorite").build()) async () => {
).resolves.toBeTruthy(); await checkMenuItemText("favorite", "Unfavorite");
}); },
true
);
await navigateTo("notes"); await navigateTo("notes");
}); });
@@ -302,7 +306,8 @@ test.describe("run tests independently", () => {
await openContextMenu(noteSelector); 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")); await page.click(getTestId("properties"));
@@ -330,12 +335,12 @@ test.describe("run tests independently", () => {
await page.waitForTimeout(500); await page.waitForTimeout(500);
await useContextMenu(noteSelector, () => clickMenuItem("unpin")); await useContextMenu(noteSelector, () => clickMenuItem("pin"));
await useContextMenu(noteSelector, () => await useContextMenu(
expect( noteSelector,
isPresent(Menu.new("menuitem").item("pin").build()) async () => await checkMenuItemText("pin", "Pin"),
).resolves.toBeTruthy() true
); );
}); });
@@ -369,7 +374,7 @@ test.describe("run tests independently", () => {
test("lock a note", async () => { test("lock a note", async () => {
const noteSelector = await createNoteAndCheckPresence(); const noteSelector = await createNoteAndCheckPresence();
await lockUnlockNote(noteSelector, "lock"); await lockUnlockNote(noteSelector);
await checkNoteLocked(noteSelector); await checkNoteLocked(noteSelector);
}); });
@@ -393,9 +398,7 @@ test.describe("run tests independently", () => {
await openContextMenu(noteSelector); await openContextMenu(noteSelector);
await expect( await checkMenuItemText("lock", "Lock");
isPresent(Menu.new("menuitem").item("lock").build())
).resolves.toBeTruthy();
await closeContextMenu(noteSelector); await closeContextMenu(noteSelector);
}); });

View File

@@ -67,7 +67,7 @@ async function createTagAndCheckPresence(title) {
async function renameTag(tagSelector, newTitle, expected) { async function renameTag(tagSelector, newTitle, expected) {
await useContextMenu(tagSelector.build(), async () => { await useContextMenu(tagSelector.build(), async () => {
await clickMenuItem("renametag"); await clickMenuItem("rename");
}); });
await page.fill(getTestId("item-dialog-title"), newTitle); 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"); const tagSelector = await createTagAndCheckPresence("helloworld");
await useContextMenu(tagSelector.build(), async () => { await useContextMenu(tagSelector.build(), async () => {
await clickMenuItem("createshortcut"); await clickMenuItem("shortcut");
}); });
expect( expect(
@@ -183,7 +183,7 @@ test("delete a shortcut of a tag", async ({ page }) => {
const tagSelector = await createTagAndCheckPresence("helloworld"); const tagSelector = await createTagAndCheckPresence("helloworld");
await useContextMenu(tagSelector.build(), async () => { await useContextMenu(tagSelector.build(), async () => {
await clickMenuItem("createshortcut"); await clickMenuItem("shortcut");
}); });
expect( expect(
@@ -208,7 +208,7 @@ test("delete the last note of a tag that is also a shortcut", async ({
const tagSelector = await createTagAndCheckPresence("helloworld"); const tagSelector = await createTagAndCheckPresence("helloworld");
await useContextMenu(tagSelector.build(), async () => { await useContextMenu(tagSelector.build(), async () => {
await clickMenuItem("createshortcut"); await clickMenuItem("shortcut");
}); });
await page.click(tagSelector.build()); await page.click(tagSelector.build());

View File

@@ -18,15 +18,15 @@ async function openContextMenu(selector) {
} }
async function closeContextMenu() { 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 openContextMenu(selector);
await action(); await action();
await closeContextMenu(); if (close) await closeContextMenu();
} }
async function confirmDialog() { async function confirmDialog() {

View File

@@ -3,6 +3,7 @@
const { expect } = require("@playwright/test"); const { expect } = require("@playwright/test");
const { getTestId, NOTE, createNote } = require("."); const { getTestId, NOTE, createNote } = require(".");
const List = require("./listitemidbuilder"); const List = require("./listitemidbuilder");
const Menu = require("./menuitemidbuilder");
async function isPresent(selector) { async function isPresent(selector) {
try { try {
@@ -59,10 +60,17 @@ async function createNoteAndCheckPresence(
return noteSelector; return noteSelector;
} }
async function checkMenuItemText(itemId, expectedText) {
await expect(
page.textContent(Menu.new("menuitem").item(itemId).build())
).resolves.toBe(expectedText);
}
module.exports = { module.exports = {
isPresent, isPresent,
isAbsent, isAbsent,
isToastPresent, isToastPresent,
checkNotePresence, checkNotePresence,
createNoteAndCheckPresence, createNoteAndCheckPresence,
checkMenuItemText,
}; };

View File

@@ -71,7 +71,7 @@ async function downloadFile(downloadActionSelector, encoding) {
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
page.on("download", async (download) => { page.on("download", async (download) => {
const path = await download.path(); const path = await download.path();
resolve(fs.readFileSync(path, { encoding }).toString()); resolve(fs.readFileSync(path, { encoding }));
}); });
await page.waitForSelector(downloadActionSelector); await page.waitForSelector(downloadActionSelector);

View File

@@ -6,6 +6,7 @@ class MenuItemIDBuilder {
} }
constructor(type) { constructor(type) {
this.type = type; this.type = type;
this.suffix = "";
} }
item(itemId) { item(itemId) {
@@ -13,18 +14,15 @@ class MenuItemIDBuilder {
return this; return this;
} }
colorCheck(color) { checked() {
this.itemId = "colors-" + color + "-check"; this.suffix = "checked";
return this;
}
color(color) {
this.itemId = "colors-" + color;
return this; return this;
} }
build() { build() {
return getTestId(`${this.type}-${this.itemId}`); return getTestId(
`${this.type}-${this.itemId}${this.suffix ? `-${this.suffix}` : ""}`
);
} }
} }
module.exports = MenuItemIDBuilder; module.exports = MenuItemIDBuilder;

View File

@@ -42,9 +42,9 @@ module.exports = {
timeout: 30000, timeout: 30000,
workers: IS_CI ? 3 : 4, workers: IS_CI ? 3 : 4,
reporter: "list", reporter: "list",
retries: IS_CI ? 3 : 1, retries: IS_CI ? 3 : 0,
use: { use: {
headless: false, headless: true,
acceptDownloads: true, acceptDownloads: true,
// Artifacts // Artifacts

View File

@@ -1,20 +1,15 @@
import { removeStatus, updateStatus } from "../hooks/use-status"; import { showMultiDeleteConfirmation } from "./dialog-controller";
import {
showMultiDeleteConfirmation,
showMultiPermanentDeleteConfirmation,
} from "./dialog-controller";
import { store as editorStore } from "../stores/editor-store";
import { store as appStore } from "../stores/app-store";
import { store as noteStore } from "../stores/note-store"; import { store as noteStore } from "../stores/note-store";
import { store as notebookStore } from "../stores/notebook-store"; import { store as notebookStore } from "../stores/notebook-store";
import { db } from "./db"; import { db } from "./db";
import { hashNavigate } from "../navigation";
import { showToast } from "../utils/toast"; import { showToast } from "../utils/toast";
import Vault from "./vault"; import Vault from "./vault";
import { showItemDeletedToast } from "./toasts"; import { showItemDeletedToast } from "./toasts";
import { TaskManager } from "./task-manager"; import { TaskManager } from "./task-manager";
async function moveNotesToTrash(notes: any[]) { async function moveNotesToTrash(notes: any[]) {
console.log(notes);
const item = notes[0]; const item = notes[0];
const isMultiselect = notes.length > 1; const isMultiselect = notes.length > 1;
if (isMultiselect) { if (isMultiselect) {

View File

@@ -68,12 +68,12 @@ function ListItem(props) {
let title = props.item.title; let title = props.item.title;
let selectedItems = selectionStore.get().selectedItems.slice(); let selectedItems = selectionStore.get().selectedItems.slice();
if (isSelected || isFocused) { if (isSelected) {
title = `${selectedItems.length} items selected`; title = `${selectedItems.length} items selected`;
items = items.filter((item) => item.multiSelect); items = items.filter((item) => item.multiSelect);
} else if (Config.get("debugMode", false)) { } else if (Config.get("debugMode", false)) {
items.push(...debugMenuItems(props.item.type)); items.push(...debugMenuItems(props.item.type));
} else { } else if (selectedItems.indexOf(props.item) === -1) {
selectedItems.push(props.item); selectedItems.push(props.item);
} }

View File

@@ -131,7 +131,10 @@ function Menu({ items, data, title, closeMenu }) {
key={item.key} key={item.key}
index={index} index={index}
item={item} item={item}
onClick={(e) => onAction(e, item)} onClick={(e) => {
if (item.items?.length) setIsSubmenuOpen(true);
else onAction(e, item);
}}
isFocused={focusIndex === index} isFocused={focusIndex === index}
onHover={() => { onHover={() => {
setFocusIndex(index); setFocusIndex(index);

View File

@@ -35,7 +35,7 @@ function MenuItem({ item, isFocused, onHover, onClick }) {
<Flex as="li" flexDirection={"column"} flex={1} onMouseOver={onHover}> <Flex as="li" flexDirection={"column"} flex={1} onMouseOver={onHover}>
<Button <Button
id={key} id={key}
data-test-id={`menuitem-${title.split(" ").join("").toLowerCase()}`} data-test-id={`menuitem-${key}`}
key={key} key={key}
ref={itemRef} ref={itemRef}
tabIndex={-1} tabIndex={-1}
@@ -65,7 +65,9 @@ function MenuItem({ item, isFocused, onHover, onClick }) {
{isPremium && <Pro size={14} color="primary" sx={{ ml: 1 }} />} {isPremium && <Pro size={14} color="primary" sx={{ ml: 1 }} />}
</Flex> </Flex>
<Flex> <Flex>
{isChecked && <Check size={14} />} {isChecked && (
<Check size={14} data-test-id={`menuitem-${key}-checked`} />
)}
{hasSubmenu && <ChevronRight size={14} />} {hasSubmenu && <ChevronRight size={14} />}
{modifier && ( {modifier && (
<Text <Text

View File

@@ -251,19 +251,7 @@ const menuItems = [
key: "colors", key: "colors",
title: "Assign color", title: "Assign color",
icon: Icon.Colors, icon: Icon.Colors,
items: COLORS.map((label) => ({ items: colorsToMenuItems(),
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());
},
})),
}, },
{ {
key: "publish", key: "publish",
@@ -300,7 +288,7 @@ const menuItems = [
isPro: true, isPro: true,
}, },
{ {
key: "unlocknote", key: "lock",
title: ({ note }) => (note.locked ? "Unlock" : "Lock"), title: ({ note }) => (note.locked ? "Unlock" : "Lock"),
icon: Icon.Lock, icon: Icon.Lock,
onClick: async ({ note }) => { onClick: async ({ note }) => {
@@ -349,3 +337,22 @@ const topicNoteMenuItems = [
multiSelect: true, 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);
},
};
});
}

View File

@@ -105,12 +105,13 @@ const pin = (notebook) => {
const menuItems = [ const menuItems = [
{ {
key: "edit",
title: "Edit", title: "Edit",
icon: Icon.NotebookEdit, icon: Icon.NotebookEdit,
onClick: ({ notebook }) => hashNavigate(`/notebooks/${notebook.id}/edit`), onClick: ({ notebook }) => hashNavigate(`/notebooks/${notebook.id}/edit`),
}, },
{ {
key: "pinnotebook", key: "pin",
icon: Icon.Pin, icon: Icon.Pin,
title: ({ notebook }) => (notebook.pinned ? "Unpin" : "Pin"), title: ({ notebook }) => (notebook.pinned ? "Unpin" : "Pin"),
onClick: ({ notebook }) => pin(notebook), onClick: ({ notebook }) => pin(notebook),
@@ -123,6 +124,7 @@ const menuItems = [
onClick: ({ notebook }) => appStore.pinItemToMenu(notebook), onClick: ({ notebook }) => appStore.pinItemToMenu(notebook),
}, },
{ {
key: "movetotrash",
title: "Move to trash", title: "Move to trash",
color: "error", color: "error",
iconColor: "error", iconColor: "error",

View File

@@ -11,6 +11,7 @@ import { showToast } from "../../utils/toast";
const menuItems = [ const menuItems = [
{ {
key: "rename",
title: "Rename tag", title: "Rename tag",
icon: Icon.Edit, icon: Icon.Edit,
onClick: ({ tag }) => { onClick: ({ tag }) => {
@@ -18,12 +19,14 @@ const menuItems = [
}, },
}, },
{ {
key: "shortcut",
title: ({ tag }) => title: ({ tag }) =>
db.settings.isPinned(tag.id) ? "Remove shortcut" : "Create shortcut", db.settings.isPinned(tag.id) ? "Remove shortcut" : "Create shortcut",
icon: Icon.Shortcut, icon: Icon.Shortcut,
onClick: ({ tag }) => appStore.pinItemToMenu(tag), onClick: ({ tag }) => appStore.pinItemToMenu(tag),
}, },
{ {
key: "delete",
color: "error", color: "error",
iconColor: "error", iconColor: "error",
title: "Delete", title: "Delete",

View File

@@ -34,6 +34,7 @@ export default TrashItem;
const menuItems = [ const menuItems = [
{ {
key: "restore",
title: "Restore", title: "Restore",
icon: Icon.Restore, icon: Icon.Restore,
onClick: ({ items }) => { onClick: ({ items }) => {
@@ -43,6 +44,7 @@ const menuItems = [
multiSelect: true, multiSelect: true,
}, },
{ {
key: "delete",
title: "Delete", title: "Delete",
icon: Icon.DeleteForver, icon: Icon.DeleteForver,
color: "error", color: "error",