mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-21 22:19:41 +01:00
mobile: fix e2e tests
This commit is contained in:
committed by
Abdullah Atta
parent
e36bc816ea
commit
e0a704d022
1
apps/mobile/.gitignore
vendored
1
apps/mobile/.gitignore
vendored
@@ -39,6 +39,7 @@ DerivedData
|
||||
*.xcuserstate
|
||||
*.hprof
|
||||
**/.xcode.env.local
|
||||
native/cache
|
||||
# Android/IntelliJ
|
||||
#
|
||||
rn-build-deps/
|
||||
|
||||
@@ -311,8 +311,10 @@ export class VaultDialog extends Component {
|
||||
loading: true
|
||||
});
|
||||
try {
|
||||
let verified = await db.user.verifyPassword(this.password);
|
||||
if (!(await db.user.getUser())) verified = true;
|
||||
let verified = true;
|
||||
if (await db.user.getUser()) {
|
||||
verified = await db.user.verifyPassword(this.password);
|
||||
}
|
||||
if (verified) {
|
||||
let noteIds = [];
|
||||
if (this.state.deleteAll) {
|
||||
@@ -320,9 +322,9 @@ export class VaultDialog extends Component {
|
||||
const relations = await db.relations.from(vault, "note").get();
|
||||
noteIds = relations.map((item) => item.toId);
|
||||
}
|
||||
|
||||
await db.vault.delete(this.state.deleteAll);
|
||||
|
||||
if (this.state.deleteAll) {
|
||||
noteIds.forEach((id) => {
|
||||
eSendEvent(
|
||||
eUpdateNoteInEditor,
|
||||
@@ -333,7 +335,8 @@ export class VaultDialog extends Component {
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
console.log("VAULT UPDATED EVENT");
|
||||
eSendEvent("vaultUpdated");
|
||||
this.setState({
|
||||
loading: false
|
||||
@@ -517,7 +520,6 @@ export class VaultDialog extends Component {
|
||||
});
|
||||
this.close();
|
||||
} else {
|
||||
eSendEvent("vaultUpdated");
|
||||
ToastManager.show({
|
||||
heading: strings.vaultCreated(),
|
||||
type: "success",
|
||||
@@ -525,6 +527,7 @@ export class VaultDialog extends Component {
|
||||
});
|
||||
this.close();
|
||||
}
|
||||
eSendEvent("vaultUpdated");
|
||||
}
|
||||
|
||||
_permanantUnlock() {
|
||||
|
||||
@@ -206,7 +206,7 @@ export const NotebookSheet = () => {
|
||||
backgroundInteractionEnabled
|
||||
gestureEnabled
|
||||
>
|
||||
<View
|
||||
{/* <View
|
||||
style={{
|
||||
position: "absolute",
|
||||
right: 24 + normalize(50),
|
||||
@@ -214,17 +214,11 @@ export const NotebookSheet = () => {
|
||||
}}
|
||||
>
|
||||
<Pressable
|
||||
testID={notesnook.buttons.add}
|
||||
testID="add-notebook-button"
|
||||
type="secondary"
|
||||
onPress={() => {
|
||||
if (!notebook) return;
|
||||
AddNotebookSheet.present(
|
||||
undefined,
|
||||
notebook,
|
||||
undefined,
|
||||
undefined,
|
||||
false
|
||||
);
|
||||
|
||||
}}
|
||||
style={{
|
||||
borderRadius: 100
|
||||
@@ -245,7 +239,7 @@ export const NotebookSheet = () => {
|
||||
/>
|
||||
</View>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View> */}
|
||||
|
||||
<View
|
||||
style={{
|
||||
@@ -404,6 +398,27 @@ export const NotebookSheet = () => {
|
||||
height: 40 * fontScale
|
||||
}}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
testID="add-notebook-button"
|
||||
name="notebook-plus"
|
||||
onPress={() => {
|
||||
if (!notebook) return;
|
||||
AddNotebookSheet.present(
|
||||
undefined,
|
||||
notebook,
|
||||
undefined,
|
||||
undefined,
|
||||
false
|
||||
);
|
||||
}}
|
||||
color={colors.primary.icon}
|
||||
size={22}
|
||||
style={{
|
||||
width: 40 * fontScale,
|
||||
height: 40 * fontScale
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
|
||||
@@ -958,7 +958,9 @@ export const useActions = ({
|
||||
title:
|
||||
item.type !== "notebook" && item.type !== "note"
|
||||
? strings.doActions.delete[
|
||||
item.type as keyof typeof strings.doActions.delete
|
||||
item.type === "trash"
|
||||
? item.itemType
|
||||
: (item.type as keyof typeof strings.doActions.delete)
|
||||
](1)
|
||||
: strings.moveToTrash(),
|
||||
icon: "delete-outline",
|
||||
|
||||
@@ -18,11 +18,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
import { db } from "../common/database";
|
||||
import BiometricService from "../services/biometrics";
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from "../services/event-manager";
|
||||
import { db } from "../common/database";
|
||||
|
||||
const VaultStatusCache = {
|
||||
const VaultStatusDefaults = {
|
||||
exists: false,
|
||||
biometryEnrolled: false,
|
||||
isBiometryAvailable: false
|
||||
@@ -35,18 +35,12 @@ export type VaultStatusType = {
|
||||
};
|
||||
|
||||
export const useVaultStatus = () => {
|
||||
const [vaultStatus, setVaultStatus] = React.useState(VaultStatusCache);
|
||||
const [vaultStatus, setVaultStatus] = React.useState(VaultStatusDefaults);
|
||||
|
||||
const checkVaultStatus = useCallback(() => {
|
||||
db.vault?.exists().then(async (exists) => {
|
||||
const available = await BiometricService.isBiometryAvailable();
|
||||
const fingerprint = await BiometricService.hasInternetCredentials();
|
||||
if (
|
||||
VaultStatusCache.exists === exists &&
|
||||
VaultStatusCache.biometryEnrolled === fingerprint &&
|
||||
VaultStatusCache.isBiometryAvailable === available
|
||||
)
|
||||
return;
|
||||
setVaultStatus({
|
||||
exists: exists,
|
||||
biometryEnrolled: fingerprint,
|
||||
|
||||
29
apps/mobile/e2e/globalSetup.ts
Normal file
29
apps/mobile/e2e/globalSetup.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { execSync } from "child_process";
|
||||
|
||||
import { pathExists, ensureDir } from "fs-extra";
|
||||
|
||||
import { resolveConfig } from "detox/internals";
|
||||
import { globalSetup } from "detox/runners/jest";
|
||||
|
||||
export default async function customGlobalSetup() {
|
||||
const config = await resolveConfig();
|
||||
if (config.device.type === "android.emulator") {
|
||||
await downloadTestButlerAPK();
|
||||
}
|
||||
|
||||
await globalSetup();
|
||||
}
|
||||
|
||||
async function downloadTestButlerAPK() {
|
||||
const version = "2.2.1";
|
||||
const artifactUrl = `https://repo1.maven.org/maven2/com/linkedin/testbutler/test-butler-app/${version}/test-butler-app-${version}.apk`;
|
||||
const filePath = `cache/test-butler-app.apk`;
|
||||
|
||||
await ensureDir("cache");
|
||||
if (!(await pathExists(filePath))) {
|
||||
console.log(`\nDownloading Test-Butler APK v${version}...`);
|
||||
execSync(`curl -f -o ${filePath} ${artifactUrl}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = customGlobalSetup;
|
||||
@@ -1,20 +1,21 @@
|
||||
/** @type {import('@jest/types').Config.InitialOptions} */
|
||||
module.exports = {
|
||||
rootDir: "..",
|
||||
testMatch: ["<rootDir>/e2e/**/*.e2e.js"],
|
||||
testTimeout: 120000,
|
||||
maxWorkers: 1,
|
||||
setupFilesAfterEnv: ["./e2e/setup.js"],
|
||||
globalSetup: "detox/runners/jest/globalSetup",
|
||||
testTimeout: 120000,
|
||||
globalSetup: "./e2e/globalSetup.ts",
|
||||
globalTeardown: "detox/runners/jest/globalTeardown",
|
||||
reporters: ["detox/runners/jest/reporter"],
|
||||
setupFilesAfterEnv: ["./e2e/setup.ts"],
|
||||
testEnvironment: "detox/runners/jest/testEnvironment",
|
||||
verbose: true,
|
||||
reporters: ["detox/runners/jest/reporter"],
|
||||
testRunner: "jest-circus/runner",
|
||||
testMatch: ["<rootDir>/e2e/**/*.e2e.(js|ts)"],
|
||||
transform: {
|
||||
"^.+\\.(js|jsx|ts|tsx)$": [
|
||||
"\\.tsx?$": "ts-jest",
|
||||
"^.+\\.(js|jsx)$": [
|
||||
"babel-jest",
|
||||
{ configFile: "../native/babel.config.js" }
|
||||
]
|
||||
},
|
||||
transformIgnorePatterns: ["<rootDir>/../node_modules/"]
|
||||
verbose: true
|
||||
};
|
||||
|
||||
@@ -74,7 +74,7 @@ async function login() {
|
||||
// }
|
||||
|
||||
describe("AUTH", () => {
|
||||
it("Login", async () => {
|
||||
it.skip("Login", async () => {
|
||||
await prepare();
|
||||
await openSideMenu();
|
||||
await login();
|
||||
|
||||
@@ -17,23 +17,22 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { navigate, tapByText, prepare, sleep } from "./utils";
|
||||
import { Tests } from "./utils";
|
||||
|
||||
describe("APP LAUNCH AND NAVIGATION", () => {
|
||||
it("App should launch successfully & hide welcome screen", async () => {
|
||||
await prepare();
|
||||
await Tests.prepare();
|
||||
});
|
||||
|
||||
it("Basic navigation should work", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
await sleep(500);
|
||||
await navigate("Favorites");
|
||||
await navigate("Trash");
|
||||
await navigate("Tags");
|
||||
await navigate("Settings");
|
||||
await navigate("Monographs");
|
||||
await navigate("Reminders");
|
||||
await navigate("Notes");
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.navigate("Favorites");
|
||||
await Tests.navigate("Trash");
|
||||
await Tests.navigate("Tags");
|
||||
await Tests.navigate("Settings");
|
||||
await Tests.navigate("Monographs");
|
||||
await Tests.navigate("Reminders");
|
||||
await Tests.navigate("Notes");
|
||||
});
|
||||
});
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { notesnook } from "../test.ids";
|
||||
import {
|
||||
navigate,
|
||||
tapById,
|
||||
visibleByText,
|
||||
createNote,
|
||||
prepare,
|
||||
visibleById,
|
||||
notVisibleById,
|
||||
sleep,
|
||||
exitEditor,
|
||||
tapByText,
|
||||
elementByText,
|
||||
elementById
|
||||
} from "./utils";
|
||||
|
||||
describe("NOTE TESTS", () => {
|
||||
it("Create a note in editor", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
});
|
||||
|
||||
it("Open and close a note", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.ids.note.get(0));
|
||||
await exitEditor();
|
||||
});
|
||||
|
||||
it.only("Notes properties should show", async () => {
|
||||
await prepare();
|
||||
let note = await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await waitFor(elementByText("Created at:")).toBeVisible().withTimeout(500);
|
||||
});
|
||||
|
||||
it("Favorite and unfavorite a note", async () => {
|
||||
await prepare();
|
||||
let note = await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-favorite");
|
||||
await visibleById("icon-star");
|
||||
await navigate("Favorites");
|
||||
await visibleByText(note.body);
|
||||
await sleep(500);
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-favorite");
|
||||
await expect(element(by.text(note.body))).not.toBeVisible();
|
||||
await navigate("Notes");
|
||||
});
|
||||
|
||||
it("Pin a note to top", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-pin");
|
||||
await visibleByText("Pinned");
|
||||
await visibleById("icon-pinned");
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-pin");
|
||||
expect(element(by.id("icon-pinned"))).not.toBeVisible();
|
||||
});
|
||||
|
||||
it("Pin a note in notifications", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-pin-to-notifications");
|
||||
await visibleByText("Unpin from notifications");
|
||||
await sleep(500);
|
||||
await tapById("icon-pin-to-notifications");
|
||||
await sleep(500);
|
||||
await visibleByText("Pin to notifications");
|
||||
});
|
||||
|
||||
it("Copy note", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await sleep(1000);
|
||||
await waitFor(elementById("icon-copy")).toBeVisible().withTimeout(500);
|
||||
await tapById("icon-copy");
|
||||
});
|
||||
|
||||
it("Assign colors to a note", async () => {
|
||||
await prepare();
|
||||
let note = await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await sleep(1000);
|
||||
await tapByText("Add color");
|
||||
await sleep(500);
|
||||
await elementById("color-title-input").typeText("Test color");
|
||||
await tapByText("Add color");
|
||||
await sleep(3000);
|
||||
await visibleById("icon-check");
|
||||
await tapById("icon-color-#efefef");
|
||||
await notVisibleById("icon-check");
|
||||
await tapById("icon-color-#efefef");
|
||||
await device.pressBack();
|
||||
await navigate("Test color");
|
||||
await visibleByText(note.body);
|
||||
});
|
||||
|
||||
it("Delete & restore a note", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await sleep(500);
|
||||
await tapById("icon-trash");
|
||||
await navigate("Trash");
|
||||
await sleep(500);
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await sleep(500);
|
||||
await tapByText("Restore note");
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await visibleByText(
|
||||
"Test note description that is very long and should not fit in text."
|
||||
);
|
||||
});
|
||||
});
|
||||
116
apps/mobile/e2e/tests/note.e2e.ts
Normal file
116
apps/mobile/e2e/tests/note.e2e.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { notesnook } from "../test.ids";
|
||||
import { Tests } from "./utils";
|
||||
|
||||
describe("NOTE TESTS", () => {
|
||||
it("Create a note in editor", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
});
|
||||
|
||||
it("Open and close a note", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await Tests.fromId(notesnook.ids.note.get(0)).waitAndTap();
|
||||
await Tests.exitEditor();
|
||||
});
|
||||
|
||||
it("Notes properties should show", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.fromText("Created at").isVisible();
|
||||
});
|
||||
|
||||
it("Favorite and unfavorite a note", async () => {
|
||||
await Tests.prepare();
|
||||
let note = await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.fromId("icon-favorite").waitAndTap();
|
||||
await Tests.fromId("icon-star").isVisible();
|
||||
await Tests.navigate("Favorites");
|
||||
await Tests.fromText(note.body).isVisible();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.fromId("icon-favorite").waitAndTap();
|
||||
await Tests.fromText(note.body).isNotVisible();
|
||||
await Tests.navigate("Notes");
|
||||
});
|
||||
|
||||
it("Pin a note to top", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.fromId("icon-pin").waitAndTap();
|
||||
await Tests.fromText("Pinned").isVisible();
|
||||
await Tests.fromId("icon-pinned").isVisible();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.fromId("icon-pin").waitAndTap();
|
||||
await Tests.fromText("icon-pinned").isNotVisible();
|
||||
});
|
||||
|
||||
it("Pin a note in notifications", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.fromId("icon-pin-to-notifications").waitAndTap();
|
||||
await Tests.fromText("Unpin from notifications").isVisible();
|
||||
await Tests.fromId("icon-pin-to-notifications").waitAndTap();
|
||||
await Tests.fromText("Pin to notifications").isVisible();
|
||||
});
|
||||
|
||||
it("Copy note", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.fromId("icon-copy").isVisible();
|
||||
await Tests.fromId("icon-copy").waitAndTap();
|
||||
});
|
||||
|
||||
it("Assign colors to a note", async () => {
|
||||
await Tests.prepare();
|
||||
let note = await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.fromText("Add color").waitAndTap();
|
||||
await Tests.fromId("color-title-input").element.typeText("Test color");
|
||||
await Tests.fromText("Add color").waitAndTap();
|
||||
await Tests.fromId("icon-check").isVisible();
|
||||
await Tests.fromId("icon-color-#efefef").waitAndTap();
|
||||
await Tests.fromId("icon-check").isNotVisible();
|
||||
await Tests.fromId("icon-color-#efefef").waitAndTap();
|
||||
await device.pressBack();
|
||||
await Tests.navigate("Test color");
|
||||
await Tests.fromText(note.body).isVisible();
|
||||
});
|
||||
|
||||
it.only("Delete & restore a note", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.fromId("icon-trash").waitAndTap();
|
||||
await Tests.navigate("Trash");
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.fromText("Restore note").waitAndTap();
|
||||
await device.pressBack();
|
||||
await Tests.fromText(
|
||||
"Test note description that is very long and should not fit in text."
|
||||
).isVisible();
|
||||
});
|
||||
});
|
||||
@@ -1,309 +0,0 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { notesnook } from "../test.ids";
|
||||
import {
|
||||
tapById,
|
||||
elementById,
|
||||
visibleByText,
|
||||
tapByText,
|
||||
createNote,
|
||||
prepare,
|
||||
notVisibleById,
|
||||
navigate,
|
||||
elementByText,
|
||||
sleep,
|
||||
notVisibleByText,
|
||||
visibleById,
|
||||
createNotebook
|
||||
} from "./utils";
|
||||
|
||||
// async function addTopic(title = "Topic") {
|
||||
// await tapById(notesnook.buttons.add);
|
||||
// await elementById("input-title").typeText(title);
|
||||
// await tapByText("Add");
|
||||
// await sleep(500);
|
||||
// }
|
||||
|
||||
describe("NOTEBOOKS", () => {
|
||||
it("Create a notebook with title only", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
await sleep(500);
|
||||
await tapByText("Add your first notebook");
|
||||
await createNotebook("Notebook 1", false, false);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await visibleByText("Notebook 1");
|
||||
});
|
||||
|
||||
it("Create a notebook title & description", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
await sleep(500);
|
||||
await tapByText("Add your first notebook");
|
||||
await createNotebook("Notebook 1", true, false);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await visibleByText("Notebook 1");
|
||||
});
|
||||
|
||||
it("Create a notebook, move notes", async () => {
|
||||
await prepare();
|
||||
let note = await createNote();
|
||||
await navigate("Notebooks");
|
||||
await sleep(500);
|
||||
await tapByText("Add your first notebook");
|
||||
await createNotebook("Notebook 1", true, true);
|
||||
await sleep(500);
|
||||
await tapById("listitem.select");
|
||||
await tapByText("Move selected notes");
|
||||
await sleep(500);
|
||||
await tapByText("Notebook 1");
|
||||
await sleep(500);
|
||||
await visibleByText(note.body);
|
||||
});
|
||||
|
||||
it("Add a sub notebook to a notebook", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
await sleep(500);
|
||||
await tapByText("Add your first notebook");
|
||||
await createNotebook("Notebook 1", true, false);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await tapByText("Notebook 1");
|
||||
await sleep(500);
|
||||
await tapById("add-notebook-button");
|
||||
await createNotebook("Sub notebook", true, true);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await visibleByText("Sub notebook");
|
||||
await tapById(notesnook.ids.notebook.menu);
|
||||
await tapByText("Move to trash");
|
||||
await sleep(300);
|
||||
await tapByText("Delete");
|
||||
await notVisibleByText("Sub notebook");
|
||||
});
|
||||
|
||||
it("Remove a sub notebook from notebook", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
await sleep(500);
|
||||
await tapByText("Add your first notebook");
|
||||
await createNotebook("Notebook 1", true, false);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await tapByText("Notebook 1");
|
||||
await sleep(500);
|
||||
await tapById("add-notebook-button");
|
||||
await createNotebook("Sub notebook", true, true);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await visibleByText("Sub notebook");
|
||||
});
|
||||
|
||||
it("Edit notebook", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
await sleep(500);
|
||||
await tapById(notesnook.buttons.add);
|
||||
await createNotebook("Notebook 1", true);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await tapById(notesnook.ids.notebook.menu);
|
||||
await tapByText("Edit notebook");
|
||||
await elementById(notesnook.ids.dialogs.notebook.inputs.title).typeText(
|
||||
" (edited)"
|
||||
);
|
||||
await tapByText("Save");
|
||||
await visibleByText("Notebook 1 (edited)");
|
||||
});
|
||||
|
||||
it("Edit a sub notebook", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
await sleep(500);
|
||||
await tapById(notesnook.buttons.add);
|
||||
await createNotebook("Notebook 1", true);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await tapByText("Notebook 1");
|
||||
await sleep(500);
|
||||
await tapById("add-notebook-button");
|
||||
await createNotebook("Sub notebook", true, true);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await tapById(notesnook.ids.notebook.menu);
|
||||
await tapByText("Edit notebook");
|
||||
await sleep(500);
|
||||
await elementById(notesnook.ids.dialogs.notebook.inputs.title).typeText(
|
||||
" (edited)"
|
||||
);
|
||||
await tapByText("Save");
|
||||
await sleep(500);
|
||||
await visibleByText("Sub notebook (edited)");
|
||||
});
|
||||
|
||||
it("Add a note to notebook", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
await tapByText("Add your first notebook");
|
||||
await sleep(500);
|
||||
await createNotebook("Notebook 1", true, true);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await tapByText("Notebook 1");
|
||||
await createNote();
|
||||
});
|
||||
|
||||
it("Remove note from Notebook", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
await tapByText("Add your first notebook");
|
||||
await createNotebook("Notebook 1", true, true);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await tapByText("Notebook 1");
|
||||
await sleep(500);
|
||||
let note = await createNote();
|
||||
await elementByText(note.body).longPress();
|
||||
await tapById("select-minus");
|
||||
await notVisibleById(note.title);
|
||||
});
|
||||
|
||||
it("Add/Remove note to notebook from home", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
await sleep(500);
|
||||
await tapByText("Add your first notebook");
|
||||
await createNotebook("Notebook 1", true, false);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await navigate("Notes");
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-notebooks");
|
||||
await sleep(500);
|
||||
await tapByText("Notebook 1");
|
||||
await tapByText("Save");
|
||||
await sleep(300);
|
||||
await visibleByText("Notebook 1");
|
||||
});
|
||||
|
||||
it("Edit notebook title, description", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
await sleep(500);
|
||||
await tapByText("Add your first notebook");
|
||||
await createNotebook();
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await visibleByText("Notebook 1");
|
||||
await tapById(notesnook.ids.notebook.menu);
|
||||
await tapByText("Edit notebook");
|
||||
await sleep(500);
|
||||
await elementById(notesnook.ids.dialogs.notebook.inputs.title).typeText(
|
||||
" (Edited)"
|
||||
);
|
||||
await elementById(
|
||||
notesnook.ids.dialogs.notebook.inputs.description
|
||||
).clearText();
|
||||
await elementById(
|
||||
notesnook.ids.dialogs.notebook.inputs.description
|
||||
).typeText("Description of Notebook 1 (Edited)");
|
||||
|
||||
await tapByText("Save");
|
||||
await sleep(500);
|
||||
await visibleByText("Notebook 1 (Edited)");
|
||||
await visibleByText("Description of Notebook 1 (Edited)");
|
||||
});
|
||||
|
||||
it.skip("Move notebook to trash", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
|
||||
await sleep(500);
|
||||
await tapByText("Add your first notebook");
|
||||
await createNotebook("Notebook 1", false, false);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await visibleByText("Notebook 1");
|
||||
await tapById(notesnook.ids.notebook.menu);
|
||||
await tapByText("Move to trash");
|
||||
await sleep(2000);
|
||||
await tapByText("Delete");
|
||||
await sleep(4000);
|
||||
await navigate("Trash");
|
||||
await visibleByText("Notebook 1");
|
||||
});
|
||||
|
||||
it("Move notebook to trash with notes", async () => {
|
||||
await prepare();
|
||||
let note = await createNote();
|
||||
await navigate("Notebooks");
|
||||
|
||||
await sleep(500);
|
||||
await tapByText("Add your first notebook");
|
||||
await createNotebook("Notebook 1", false, true);
|
||||
await sleep(500);
|
||||
await tapById("listitem.select");
|
||||
await tapByText("Move selected notes");
|
||||
await sleep(500);
|
||||
await visibleByText("Notebook 1");
|
||||
await tapById(notesnook.ids.notebook.menu);
|
||||
await tapByText("Move to trash");
|
||||
await sleep(2000);
|
||||
await tapByText("Move all notes in this notebook to trash");
|
||||
await sleep(500);
|
||||
await tapByText("Delete");
|
||||
await sleep(4000);
|
||||
await navigate("Trash");
|
||||
await visibleByText("Notebook 1");
|
||||
await visibleByText(note.body);
|
||||
});
|
||||
|
||||
it("Pin notebook to side menu", async () => {
|
||||
await prepare();
|
||||
await navigate("Notebooks");
|
||||
|
||||
await sleep(500);
|
||||
await tapByText("Add your first notebook");
|
||||
await createNotebook("Notebook 1", false, false);
|
||||
await sleep(500);
|
||||
await device.pressBack();
|
||||
await sleep(500);
|
||||
await visibleByText("Notebook 1");
|
||||
await tapById(notesnook.ids.notebook.menu);
|
||||
await tapByText("Add Shortcut");
|
||||
let menu = elementById(notesnook.ids.default.header.buttons.left);
|
||||
await menu.tap();
|
||||
await visibleByText("Notebook 1");
|
||||
});
|
||||
});
|
||||
233
apps/mobile/e2e/tests/notebook.e2e.ts
Normal file
233
apps/mobile/e2e/tests/notebook.e2e.ts
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { notesnook } from "../test.ids";
|
||||
import { Tests } from "./utils";
|
||||
|
||||
describe("NOTEBOOKS", () => {
|
||||
it("Create a notebook with title only", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", false);
|
||||
await device.pressBack();
|
||||
await Tests.fromText("Notebook 1").isVisible();
|
||||
});
|
||||
|
||||
it("Create a notebook title & description", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", true);
|
||||
await device.pressBack();
|
||||
await Tests.fromText("Notebook 1").isVisible();
|
||||
});
|
||||
|
||||
it("Create a notebook, move notes", async () => {
|
||||
await Tests.prepare();
|
||||
let note = await Tests.createNote();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", true);
|
||||
await Tests.fromId("listitem.select").waitAndTap();
|
||||
await Tests.fromText("Move selected notes").waitAndTap();
|
||||
await Tests.fromText("Notebook 1").waitAndTap();
|
||||
await Tests.fromText(note.body).isVisible();
|
||||
});
|
||||
|
||||
it("Add a sub notebook to a notebook", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", true);
|
||||
await device.pressBack();
|
||||
await Tests.fromText("Notebook 1").waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromId("add-notebook-button").waitAndTap();
|
||||
await Tests.createNotebook("Sub notebook", true);
|
||||
await Tests.fromText("Sub notebook").isVisible();
|
||||
await Tests.fromId(notesnook.ids.notebook.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Move to trash").waitAndTap();
|
||||
await Tests.fromText("Delete").waitAndTap();
|
||||
await Tests.fromText("Sub notebook").isNotVisible();
|
||||
});
|
||||
|
||||
it("Remove a sub notebook from notebook", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", true);
|
||||
await device.pressBack();
|
||||
await Tests.fromText("Notebook 1").waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromId("add-notebook-button").waitAndTap();
|
||||
await Tests.createNotebook("Sub notebook", true);
|
||||
await Tests.fromText("Sub notebook").isVisible();
|
||||
});
|
||||
|
||||
it("Edit notebook", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromId(notesnook.buttons.add).waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", true);
|
||||
await device.pressBack();
|
||||
await Tests.fromId(notesnook.ids.notebook.menu).waitAndTap();
|
||||
await Tests.fromText("Edit notebook").waitAndTap();
|
||||
await Tests.fromId(
|
||||
notesnook.ids.dialogs.notebook.inputs.title
|
||||
).element.typeText(" (edited)");
|
||||
await Tests.fromText("Save").waitAndTap();
|
||||
await Tests.fromText("Notebook 1 (edited)").isVisible();
|
||||
});
|
||||
|
||||
it("Edit a sub notebook", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromId(notesnook.buttons.add).waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", true);
|
||||
await device.pressBack();
|
||||
await Tests.fromText("Notebook 1").waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromId("add-notebook-button").waitAndTap();
|
||||
await Tests.createNotebook("Sub notebook", true);
|
||||
await Tests.fromId(notesnook.ids.notebook.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Edit notebook").waitAndTap();
|
||||
await Tests.fromId(
|
||||
notesnook.ids.dialogs.notebook.inputs.title
|
||||
).element.typeText(" (edited)");
|
||||
await Tests.fromText("Save").waitAndTap();
|
||||
await Tests.fromText("Sub notebook (edited)").isVisible();
|
||||
});
|
||||
|
||||
it("Add a note to notebook", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", true);
|
||||
await device.pressBack();
|
||||
await Tests.fromText("Notebook 1").waitAndTap();
|
||||
await Tests.createNote();
|
||||
});
|
||||
|
||||
it.skip("Remove note from Notebook", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", true);
|
||||
await device.pressBack();
|
||||
await Tests.fromText("Notebook 1").waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
let note = await Tests.createNote();
|
||||
await Tests.fromText(note.body).element.longPress();
|
||||
await Tests.fromId("select-minus").waitAndTap();
|
||||
await Tests.fromId(note.title).isNotVisible();
|
||||
});
|
||||
|
||||
it("Add/Remove note to notebook from home", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", true);
|
||||
await device.pressBack();
|
||||
await Tests.navigate("Notes");
|
||||
await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromId("icon-notebooks").waitAndTap();
|
||||
await Tests.fromText("Notebook 1").waitAndTap();
|
||||
await Tests.fromText("Save").waitAndTap();
|
||||
await Tests.fromText("Notebook 1").isVisible();
|
||||
});
|
||||
|
||||
it("Edit notebook title, description", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook();
|
||||
await device.pressBack();
|
||||
await Tests.fromText("Notebook 1").isVisible();
|
||||
await Tests.fromId(notesnook.ids.notebook.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Edit notebook").waitAndTap();
|
||||
await Tests.fromId(
|
||||
notesnook.ids.dialogs.notebook.inputs.title
|
||||
).element.typeText(" (Edited)");
|
||||
await Tests.fromId(
|
||||
notesnook.ids.dialogs.notebook.inputs.description
|
||||
).element.clearText();
|
||||
await Tests.fromId(
|
||||
notesnook.ids.dialogs.notebook.inputs.description
|
||||
).element.typeText("Description of Notebook 1 (Edited)");
|
||||
await Tests.fromText("Save").waitAndTap();
|
||||
await Tests.fromText("Notebook 1 (Edited)").isVisible();
|
||||
await Tests.fromText("Description of Notebook 1 (Edited)").isVisible();
|
||||
});
|
||||
|
||||
it.skip("Move notebook to trash", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", false);
|
||||
await device.pressBack();
|
||||
await Tests.fromText("Notebook 1").isVisible();
|
||||
await Tests.fromId(notesnook.ids.notebook.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Move to trash").waitAndTap();
|
||||
await Tests.fromText("Delete").waitAndTap();
|
||||
await Tests.navigate("Trash");
|
||||
await Tests.fromText("Notebook 1").isVisible();
|
||||
});
|
||||
|
||||
it("Move notebook to trash with notes", async () => {
|
||||
await Tests.prepare();
|
||||
let note = await Tests.createNote();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", false);
|
||||
await Tests.fromId("listitem.select").waitAndTap();
|
||||
await Tests.fromText("Move selected notes").waitAndTap();
|
||||
await Tests.fromText("Notebook 1").isVisible();
|
||||
await Tests.fromId(notesnook.ids.notebook.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Move to trash").waitAndTap();
|
||||
await Tests.fromText(
|
||||
"Move all notes in this notebook to trash"
|
||||
).waitAndTap();
|
||||
await Tests.fromText("Delete").waitAndTap();
|
||||
await Tests.navigate("Trash");
|
||||
await Tests.fromText("Notebook 1").isVisible();
|
||||
await Tests.fromText(note.body).isVisible();
|
||||
});
|
||||
|
||||
it.skip("Pin notebook to side menu", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.navigate("Notebooks");
|
||||
await Tests.fromText("Add your first notebook").waitAndTap();
|
||||
await Tests.createNotebook("Notebook 1", false);
|
||||
await device.pressBack();
|
||||
await Tests.fromText("Notebook 1").isVisible();
|
||||
await Tests.fromId(notesnook.ids.notebook.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Add Shortcut").waitAndTap();
|
||||
await Tests.fromId(notesnook.ids.default.header.buttons.left).waitAndTap();
|
||||
await Tests.fromText("Notebook 1").isVisible();
|
||||
});
|
||||
});
|
||||
@@ -17,29 +17,17 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { notesnook } from "../test.ids";
|
||||
import {
|
||||
tapById,
|
||||
visibleByText,
|
||||
createNote,
|
||||
prepare,
|
||||
elementById,
|
||||
sleep,
|
||||
tapByText
|
||||
} from "./utils";
|
||||
import { Tests } from "./utils";
|
||||
|
||||
describe("Search", () => {
|
||||
it("Search for a note", async () => {
|
||||
await prepare();
|
||||
let note = await createNote();
|
||||
await tapById("icon-search");
|
||||
await sleep(300);
|
||||
await elementById("search-input").typeText("Test");
|
||||
await sleep(1000);
|
||||
await tapByText(note.body);
|
||||
await sleep(1000);
|
||||
await Tests.prepare();
|
||||
let note = await Tests.createNote();
|
||||
await Tests.fromId("icon-search").waitAndTap();
|
||||
await Tests.fromId("search-input").element.typeText("Test");
|
||||
await Tests.fromText(note.body).waitAndTap();
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await visibleByText(note.body);
|
||||
await Tests.fromText(note.body).isVisible();
|
||||
});
|
||||
});
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { notesnook } from "../test.ids";
|
||||
import {
|
||||
tapById,
|
||||
visibleByText,
|
||||
createNote,
|
||||
prepare,
|
||||
tapByText,
|
||||
notVisibleByText,
|
||||
sleep,
|
||||
navigate,
|
||||
createNotebook
|
||||
} from "./utils";
|
||||
|
||||
async function sortBy(sorting, elementText = "Default") {
|
||||
await tapByText(elementText);
|
||||
await tapByText(sorting);
|
||||
await device.pressBack();
|
||||
}
|
||||
|
||||
describe("Sort & filter", () => {
|
||||
it("Sort by date-edited/date-created", async () => {
|
||||
await prepare();
|
||||
let webview = web(by.id(notesnook.editor.id));
|
||||
await createNote("Note 1", "Note 1");
|
||||
await sleep(300);
|
||||
await createNote("Note 2", "Note 2");
|
||||
await sleep(300);
|
||||
await tapByText("Note 1");
|
||||
await sleep(500);
|
||||
await expect(webview.element(by.web.className("ProseMirror"))).toExist();
|
||||
await webview.element(by.web.className("ProseMirror")).tap();
|
||||
await webview
|
||||
.element(by.web.className("ProseMirror"))
|
||||
.typeText("Edited ", true);
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await sortBy("Date created");
|
||||
await tapById(notesnook.listitem.menu);
|
||||
//await visibleByText("Note 2");
|
||||
await device.pressBack();
|
||||
await sortBy("Date edited");
|
||||
await tapById(notesnook.listitem.menu);
|
||||
//await visibleByText("Edited Note 1");
|
||||
await device.pressBack();
|
||||
});
|
||||
|
||||
it("Disable grouping", async () => {
|
||||
await prepare();
|
||||
await createNote("Note 1", "Note 1");
|
||||
await sleep(300);
|
||||
await sortBy("None");
|
||||
await sleep(300);
|
||||
await visibleByText("None");
|
||||
});
|
||||
|
||||
it("Group by Abc", async () => {
|
||||
await prepare();
|
||||
await createNote("Note 1", "Note 1");
|
||||
await sleep(300);
|
||||
await sortBy("Abc");
|
||||
await visibleByText("N");
|
||||
});
|
||||
|
||||
it("Group by Year", async () => {
|
||||
await prepare();
|
||||
await createNote("Note 1", "Note 1");
|
||||
await sleep(300);
|
||||
await sortBy("Year");
|
||||
await sleep(300);
|
||||
await visibleByText("Year");
|
||||
});
|
||||
|
||||
it("Group by Week", async () => {
|
||||
await prepare();
|
||||
await createNote("Note 1", "Note 1");
|
||||
await sleep(300);
|
||||
await sortBy("Week");
|
||||
await sleep(300);
|
||||
await visibleByText("Week");
|
||||
});
|
||||
|
||||
it("Group by Month", async () => {
|
||||
await prepare();
|
||||
await createNote("Note 1", "Note 1");
|
||||
await sleep(300);
|
||||
await sortBy("Month");
|
||||
await sleep(300);
|
||||
await visibleByText("Month");
|
||||
});
|
||||
|
||||
it("Compact mode", async () => {
|
||||
await prepare();
|
||||
await createNote("Note 1", "Note 1");
|
||||
await sleep(300);
|
||||
await tapById("icon-compact-mode");
|
||||
await sleep(300);
|
||||
await notVisibleByText("Note 1");
|
||||
await tapById("icon-compact-mode");
|
||||
await sleep(300);
|
||||
await visibleByText("Note 1");
|
||||
});
|
||||
});
|
||||
93
apps/mobile/e2e/tests/sort.e2e.ts
Normal file
93
apps/mobile/e2e/tests/sort.e2e.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { notesnook } from "../test.ids";
|
||||
import { Tests } from "./utils";
|
||||
|
||||
async function sortBy(sorting: string, elementText = "Default") {
|
||||
await Tests.fromText(elementText).waitAndTap();
|
||||
await Tests.fromText(sorting).waitAndTap();
|
||||
await device.pressBack();
|
||||
}
|
||||
|
||||
describe("Sort & filter", () => {
|
||||
it("Sort by date-edited/date-created", async () => {
|
||||
await Tests.prepare();
|
||||
let webview = web();
|
||||
await Tests.createNote("Note 1", "Note 1");
|
||||
await Tests.createNote("Note 2", "Note 2");
|
||||
await Tests.fromText("Note 1").waitAndTap();
|
||||
await webview.element(by.web.className("ProseMirror")).tap();
|
||||
await webview
|
||||
.element(by.web.className("ProseMirror"))
|
||||
.typeText("Edited ", true);
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await sortBy("Date created");
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await device.pressBack();
|
||||
await sortBy("Date edited");
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await device.pressBack();
|
||||
});
|
||||
|
||||
it("Disable grouping", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote("Note 1", "Note 1");
|
||||
await sortBy("None");
|
||||
await Tests.fromText("Default").isNotVisible();
|
||||
});
|
||||
|
||||
it("Group by Abc", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote("Note 1", "Note 1");
|
||||
await sortBy("Abc");
|
||||
await Tests.fromText("N").isVisible();
|
||||
});
|
||||
|
||||
it("Group by Year", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote("Note 1", "Note 1");
|
||||
await sortBy("Year");
|
||||
await Tests.fromText("Year").isVisible();
|
||||
});
|
||||
|
||||
it("Group by Week", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote("Note 1", "Note 1");
|
||||
await sortBy("Week");
|
||||
await Tests.fromText("Week").isVisible();
|
||||
});
|
||||
|
||||
it("Group by Month", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote("Note 1", "Note 1");
|
||||
await sortBy("Month");
|
||||
await Tests.fromText("Month").isVisible();
|
||||
});
|
||||
|
||||
it("Compact mode", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote("Note 1", "Note 1");
|
||||
await Tests.fromId("icon-compact-mode").waitAndTap();
|
||||
await Tests.fromText("Note 1").isNotVisible();
|
||||
await Tests.fromId("icon-compact-mode").waitAndTap();
|
||||
await Tests.fromText("Note 1").isVisible();
|
||||
});
|
||||
});
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { notesnook } from "../test.ids";
|
||||
import {
|
||||
navigate,
|
||||
tapById,
|
||||
visibleByText,
|
||||
createNote,
|
||||
prepare,
|
||||
elementById,
|
||||
tapByText,
|
||||
notVisibleByText,
|
||||
sleep
|
||||
} from "./utils";
|
||||
|
||||
describe("Tags", () => {
|
||||
it("Tag a note", async () => {
|
||||
await prepare();
|
||||
let note = await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapByText("Add tags");
|
||||
await elementById("tag-input").typeText("testtag");
|
||||
await tapByText('Add "#testtag"');
|
||||
await visibleByText("#testtag");
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await navigate("Tags");
|
||||
await tapByText("#testtag");
|
||||
await visibleByText(note.body);
|
||||
});
|
||||
|
||||
it("Untag a note", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapByText("Add tags");
|
||||
await elementById("tag-input").typeText("testtag");
|
||||
await tapByText('Add "#testtag"');
|
||||
await visibleByText("#testtag");
|
||||
await tapByText("#testtag");
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await notVisibleByText("#testtag");
|
||||
});
|
||||
|
||||
it("Creat shortcut of a tag", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapByText("Add tags");
|
||||
await elementById("tag-input").typeText("testtag");
|
||||
await tapByText('Add "#testtag"');
|
||||
await visibleByText("#testtag");
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await navigate("Tags");
|
||||
await sleep(500);
|
||||
await tapById(notesnook.ids.tag.menu);
|
||||
await sleep(500);
|
||||
await tapByText("Add Shortcut");
|
||||
let menu = elementById(notesnook.ids.default.header.buttons.left);
|
||||
await menu.tap();
|
||||
await visibleByText("#testtag");
|
||||
});
|
||||
|
||||
it("Rename a tag", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapByText("Add tags");
|
||||
await elementById("tag-input").typeText("testtag");
|
||||
await tapByText('Add "#testtag"');
|
||||
await visibleByText("#testtag");
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await navigate("Tags");
|
||||
await tapById(notesnook.ids.tag.menu);
|
||||
await sleep(500);
|
||||
await tapByText("Rename tag");
|
||||
await sleep(500);
|
||||
await elementById("input-value").clearText();
|
||||
await elementById("input-value").typeText("testtag_edited");
|
||||
await tapByText("Save");
|
||||
await visibleByText("#testtag_edited");
|
||||
});
|
||||
});
|
||||
95
apps/mobile/e2e/tests/tag.e2e.ts
Normal file
95
apps/mobile/e2e/tests/tag.e2e.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { notesnook } from "../test.ids";
|
||||
import { Tests } from "./utils";
|
||||
|
||||
describe("Tags", () => {
|
||||
it("Tag a note", async () => {
|
||||
await Tests.prepare();
|
||||
let note = await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Add tag").waitAndTap();
|
||||
await Tests.fromId("tag-input").element.typeText("testtag");
|
||||
await Tests.fromText('Add "#testtag"').waitAndTap();
|
||||
await Tests.fromText("#testtag").isVisible();
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await Tests.navigate("Tags");
|
||||
await Tests.fromText("#testtag").waitAndTap();
|
||||
await Tests.fromText(note.body).isVisible();
|
||||
});
|
||||
|
||||
it("Untag a note", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Add tag").waitAndTap();
|
||||
await Tests.fromId("tag-input").element.typeText("testtag");
|
||||
await Tests.fromText('Add "#testtag"').waitAndTap();
|
||||
await Tests.fromText("#testtag").isVisible();
|
||||
await Tests.fromText("#testtag").waitAndTap();
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await Tests.fromText("#testtag").isNotVisible();
|
||||
});
|
||||
|
||||
it("Create shortcut of a tag", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Add tag").waitAndTap();
|
||||
await Tests.fromId("tag-input").element.typeText("testtag");
|
||||
await Tests.fromText('Add "#testtag"').waitAndTap();
|
||||
await Tests.fromText("#testtag").isVisible();
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await Tests.navigate("Tags");
|
||||
await Tests.fromId(notesnook.ids.tag.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Add shortcut").waitAndTap();
|
||||
await Tests.fromId(notesnook.ids.default.header.buttons.left).waitAndTap();
|
||||
await Tests.fromText("testtag").isVisible();
|
||||
});
|
||||
|
||||
it("Rename a tag", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Add tag").waitAndTap();
|
||||
await Tests.fromId("tag-input").element.typeText("testtag");
|
||||
await Tests.fromText('Add "#testtag"').waitAndTap();
|
||||
await Tests.fromText("#testtag").isVisible();
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await Tests.navigate("Tags");
|
||||
await Tests.fromId(notesnook.ids.tag.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Rename").waitAndTap();
|
||||
await Tests.sleep(100);
|
||||
await Tests.fromId("input-value").element.clearText();
|
||||
await Tests.fromId("input-value").element.typeText("testtag_edited");
|
||||
await Tests.fromText("Save").waitAndTap();
|
||||
await Tests.fromText("#testtag_edited").isVisible();
|
||||
});
|
||||
});
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { notesnook } from "../test.ids";
|
||||
import { readFileSync } from "fs";
|
||||
import { expect as jestExpect } from "@jest/globals";
|
||||
import { toMatchImageSnapshot } from "jest-image-snapshot";
|
||||
import { device as _device } from "detox";
|
||||
jestExpect.extend({ toMatchImageSnapshot });
|
||||
|
||||
const sleep = (duration) =>
|
||||
new Promise((resolve) =>
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
}, duration)
|
||||
);
|
||||
|
||||
async function LaunchApp() {
|
||||
await waitFor(element(by.id(notesnook.ids.default.root)))
|
||||
.toBeVisible()
|
||||
.withTimeout(500);
|
||||
}
|
||||
|
||||
function elementById(id) {
|
||||
return element(by.id(id)).atIndex(0);
|
||||
}
|
||||
|
||||
function elementByText(text) {
|
||||
return element(by.text(text)).atIndex(0);
|
||||
}
|
||||
|
||||
async function tapById(id) {
|
||||
await elementById(id).tap();
|
||||
}
|
||||
|
||||
async function tapByText(text) {
|
||||
await elementByText(text).tap();
|
||||
}
|
||||
|
||||
async function visibleByText(text) {
|
||||
await expect(elementByText(text)).toBeVisible();
|
||||
}
|
||||
|
||||
async function visibleById(id) {
|
||||
await expect(elementById(id)).toBeVisible();
|
||||
}
|
||||
|
||||
async function notVisibleById(id) {
|
||||
await expect(elementById(id)).not.toBeVisible();
|
||||
}
|
||||
|
||||
async function notVisibleByText(text) {
|
||||
await expect(elementByText(text)).not.toBeVisible();
|
||||
}
|
||||
|
||||
async function exitEditor() {
|
||||
await _device.pressBack();
|
||||
await _device.pressBack();
|
||||
}
|
||||
|
||||
async function createNote(_title, _body) {
|
||||
let title = _title || "Test note description that ";
|
||||
let body =
|
||||
_body ||
|
||||
"Test note description that is very long and should not fit in text.";
|
||||
await tapById(notesnook.buttons.add);
|
||||
let webview = web(by.id(notesnook.editor.id));
|
||||
await expect(webview.element(by.web.className("ProseMirror"))).toExist();
|
||||
await webview.element(by.web.className("ProseMirror")).tap();
|
||||
await webview.element(by.web.className("ProseMirror")).typeText(body, true);
|
||||
await exitEditor();
|
||||
await waitFor(element(by.text(body)))
|
||||
.toBeVisible()
|
||||
.withTimeout(500);
|
||||
|
||||
return { title, body };
|
||||
}
|
||||
|
||||
async function openSideMenu() {
|
||||
let menu = elementById(notesnook.ids.default.header.buttons.left);
|
||||
await menu.tap();
|
||||
}
|
||||
|
||||
async function navigate(screen) {
|
||||
let menu = elementById(notesnook.ids.default.header.buttons.left);
|
||||
await waitFor(menu).toBeVisible().withTimeout(300);
|
||||
await menu.tap();
|
||||
|
||||
await waitFor(elementByText(screen)).toBeVisible().withTimeout(300);
|
||||
await elementByText(screen).tap();
|
||||
}
|
||||
|
||||
const testvars = {
|
||||
isFirstTest: true
|
||||
};
|
||||
|
||||
async function prepare() {
|
||||
await device.disableSynchronization();
|
||||
if (testvars.isFirstTest) {
|
||||
testvars.isFirstTest = false;
|
||||
return await LaunchApp();
|
||||
}
|
||||
await device.reverseTcpPort(8081);
|
||||
await device.uninstallApp();
|
||||
await device.installApp();
|
||||
await device.launchApp({ newInstance: true });
|
||||
await LaunchApp();
|
||||
}
|
||||
|
||||
async function matchSnapshot(element, name) {
|
||||
let path = await element.takeScreenshot(name);
|
||||
const bitmapBuffer = readFileSync(path);
|
||||
jestExpect(bitmapBuffer).toMatchImageSnapshot({
|
||||
failureThreshold: 200,
|
||||
failureThresholdType: "pixel"
|
||||
});
|
||||
}
|
||||
|
||||
async function createNotebook(title = "Notebook 1", description = true) {
|
||||
await elementById(notesnook.ids.dialogs.notebook.inputs.title).typeText(
|
||||
title
|
||||
);
|
||||
if (description) {
|
||||
await elementById(
|
||||
notesnook.ids.dialogs.notebook.inputs.description
|
||||
).typeText(`Description of ${title}`);
|
||||
}
|
||||
await tapByText("Add");
|
||||
await sleep(300);
|
||||
}
|
||||
|
||||
export {
|
||||
matchSnapshot,
|
||||
createNotebook,
|
||||
prepare,
|
||||
LaunchApp,
|
||||
createNote,
|
||||
navigate,
|
||||
openSideMenu,
|
||||
notVisibleById,
|
||||
notVisibleByText,
|
||||
visibleById,
|
||||
visibleByText,
|
||||
tapById,
|
||||
tapByText,
|
||||
elementByText,
|
||||
elementById,
|
||||
sleep,
|
||||
exitEditor
|
||||
};
|
||||
149
apps/mobile/e2e/tests/utils.ts
Normal file
149
apps/mobile/e2e/tests/utils.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { expect as jestExpect } from "@jest/globals";
|
||||
import { device as _device, expect } from "detox";
|
||||
import { readFileSync } from "fs";
|
||||
import { toMatchImageSnapshot } from "jest-image-snapshot";
|
||||
import type { RouteName } from "../../app/stores/use-navigation-store";
|
||||
import { notesnook } from "../test.ids";
|
||||
jestExpect.extend({ toMatchImageSnapshot });
|
||||
|
||||
const testvars = {
|
||||
isFirstTest: true
|
||||
};
|
||||
|
||||
class Element {
|
||||
element: Detox.NativeElement;
|
||||
constructor(public type: "id" | "text", public value: string) {
|
||||
if (type == "id") {
|
||||
this.element = element(by.id(value)).atIndex(0);
|
||||
} else {
|
||||
this.element = element(by.text(value)).atIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
isVisible(timeout?: number) {
|
||||
return waitFor(this.element)
|
||||
.toBeVisible()
|
||||
.withTimeout(timeout || 500);
|
||||
}
|
||||
|
||||
isNotVisible(timeout?: number) {
|
||||
return waitFor(this.element)
|
||||
.not.toBeVisible()
|
||||
.withTimeout(timeout || 500);
|
||||
}
|
||||
|
||||
async waitAndTap(timeout?: number) {
|
||||
await waitFor(this.element)
|
||||
.toBeVisible()
|
||||
.withTimeout(timeout || 500);
|
||||
await this.element.tap();
|
||||
}
|
||||
|
||||
tap(point?: Detox.Point2D): Promise<void> {
|
||||
return this.element.tap(point);
|
||||
}
|
||||
|
||||
static fromId(id: string) {
|
||||
return new Element("id", id);
|
||||
}
|
||||
static fromText(text: string) {
|
||||
return new Element("text", text);
|
||||
}
|
||||
}
|
||||
|
||||
const Tests = {
|
||||
awaitLaunch: async () => {
|
||||
await waitFor(element(by.id(notesnook.ids.default.root)))
|
||||
.toBeVisible()
|
||||
.withTimeout(500);
|
||||
},
|
||||
sleep: (duration: number) => {
|
||||
return new Promise((resolve) =>
|
||||
setTimeout(() => {
|
||||
resolve(undefined);
|
||||
}, duration)
|
||||
);
|
||||
},
|
||||
fromId: Element.fromId,
|
||||
fromText: Element.fromText,
|
||||
async exitEditor() {
|
||||
await _device.pressBack();
|
||||
await _device.pressBack();
|
||||
},
|
||||
async createNote(_title?: string, _body?: string) {
|
||||
let title = _title || "Test note description that ";
|
||||
let body =
|
||||
_body ||
|
||||
"Test note description that is very long and should not fit in text.";
|
||||
await Tests.fromId(notesnook.buttons.add).tap();
|
||||
await expect(web().element(by.web.className("ProseMirror"))).toExist();
|
||||
// await web().element(by.web.className("ProseMirror")).tap();
|
||||
await web().element(by.web.className("ProseMirror")).typeText(body, true);
|
||||
await Tests.exitEditor();
|
||||
await Tests.fromText(body).isVisible();
|
||||
return { title, body };
|
||||
},
|
||||
async navigate(screen: RouteName | ({} & string)) {
|
||||
let menu = Tests.fromId(notesnook.ids.default.header.buttons.left);
|
||||
await menu.waitAndTap();
|
||||
await Tests.fromText(screen).waitAndTap();
|
||||
},
|
||||
async openSideMenu() {
|
||||
await Tests.fromId(notesnook.ids.default.header.buttons.left).waitAndTap();
|
||||
},
|
||||
async prepare() {
|
||||
await device.disableSynchronization();
|
||||
if (testvars.isFirstTest) {
|
||||
testvars.isFirstTest = false;
|
||||
return await Tests.awaitLaunch();
|
||||
}
|
||||
await device.reverseTcpPort(8081);
|
||||
await device.uninstallApp();
|
||||
await device.installApp();
|
||||
await device.launchApp({ newInstance: true });
|
||||
await Tests.awaitLaunch();
|
||||
},
|
||||
async createNotebook(title = "Notebook 1", description = true) {
|
||||
await Tests.sleep(1000);
|
||||
const titleInput = Tests.fromId(
|
||||
notesnook.ids.dialogs.notebook.inputs.title
|
||||
);
|
||||
await titleInput.isVisible();
|
||||
await titleInput.element.typeText(title);
|
||||
if (description) {
|
||||
await Tests.fromId(
|
||||
notesnook.ids.dialogs.notebook.inputs.description
|
||||
).element.typeText(`Description of ${title}`);
|
||||
}
|
||||
await Tests.fromText("Add").waitAndTap();
|
||||
},
|
||||
async matchSnapshot(element: Element, name: string) {
|
||||
let path = await element.element.takeScreenshot(name);
|
||||
const bitmapBuffer = readFileSync(path);
|
||||
(jestExpect(bitmapBuffer) as any).toMatchImageSnapshot({
|
||||
failureThreshold: 200,
|
||||
failureThresholdType: "pixel"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export { Element, Tests };
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { notesnook } from "../test.ids";
|
||||
import {
|
||||
tapById,
|
||||
elementById,
|
||||
visibleByText,
|
||||
tapByText,
|
||||
createNote,
|
||||
prepare,
|
||||
visibleById,
|
||||
matchSnapshot,
|
||||
notVisibleById,
|
||||
navigate
|
||||
} from "./utils";
|
||||
import { sleep } from "./utils";
|
||||
|
||||
async function lockNote() {
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-lock-unlock");
|
||||
await sleep(1000);
|
||||
await visibleByText("Lock");
|
||||
await elementById(notesnook.ids.dialogs.vault.pwd).typeText("1234");
|
||||
await elementById(notesnook.ids.dialogs.vault.pwdAlt).typeText("1234");
|
||||
await tapByText("Lock");
|
||||
await sleep(500);
|
||||
await visibleById("note-locked-icon");
|
||||
}
|
||||
|
||||
async function removeFromVault() {
|
||||
await tapById(notesnook.listitem.menu);
|
||||
await tapById("icon-lock-unlock");
|
||||
await sleep(1000);
|
||||
await elementById(notesnook.ids.dialogs.vault.pwd).typeText("1234");
|
||||
await tapByText("Unlock");
|
||||
await sleep(1000);
|
||||
await notVisibleById("note-locked-icon");
|
||||
}
|
||||
|
||||
async function openLockedNote(pwd) {
|
||||
await tapById(notesnook.ids.note.get(1));
|
||||
await sleep(1000);
|
||||
await visibleByText("Open");
|
||||
await elementById(notesnook.ids.dialogs.vault.pwd).typeText(pwd || "1234");
|
||||
await tapByText("Open");
|
||||
await sleep(3000);
|
||||
await matchSnapshot(elementById("editor-wrapper"), "note-after-vault-unlock");
|
||||
}
|
||||
|
||||
async function goToPrivacySecuritySettings() {
|
||||
await navigate("Settings");
|
||||
await tapByText("Vault");
|
||||
await sleep(500);
|
||||
}
|
||||
|
||||
describe("VAULT", () => {
|
||||
it("Create vault from settings", async () => {
|
||||
await prepare();
|
||||
await goToPrivacySecuritySettings();
|
||||
await tapByText("Create vault");
|
||||
await elementById(notesnook.ids.dialogs.vault.pwd).typeText("1234");
|
||||
await elementById(notesnook.ids.dialogs.vault.pwdAlt).typeText("1234");
|
||||
await tapByText("Create");
|
||||
await sleep(500);
|
||||
await visibleByText("Clear vault");
|
||||
});
|
||||
|
||||
it("Change vault password", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await lockNote();
|
||||
await goToPrivacySecuritySettings();
|
||||
await tapByText("Change vault password");
|
||||
await elementById(notesnook.ids.dialogs.vault.pwd).typeText("1234");
|
||||
await elementById(notesnook.ids.dialogs.vault.changePwd).typeText("2362");
|
||||
await tapByText("Change");
|
||||
await sleep(2000);
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await openLockedNote("2362");
|
||||
});
|
||||
|
||||
it("Delete vault", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await lockNote();
|
||||
await goToPrivacySecuritySettings();
|
||||
await tapByText("Delete vault");
|
||||
await elementById(notesnook.ids.dialogs.vault.pwd).typeText("1234");
|
||||
await tapByText("Delete");
|
||||
await sleep(500);
|
||||
await visibleByText("Create vault");
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await visibleById(notesnook.listitem.menu);
|
||||
});
|
||||
|
||||
it("Delete vault with locked notes", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await lockNote();
|
||||
await goToPrivacySecuritySettings();
|
||||
await tapByText("Delete vault");
|
||||
await elementById(notesnook.ids.dialogs.vault.pwd).typeText("1234");
|
||||
await tapByText("Delete all notes");
|
||||
await tapByText("Delete");
|
||||
await sleep(500);
|
||||
await visibleByText("Create vault");
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await notVisibleById(notesnook.listitem.menu);
|
||||
});
|
||||
|
||||
it("Add a note to vault", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await lockNote();
|
||||
await openLockedNote();
|
||||
});
|
||||
|
||||
it("Remove note from vault", async () => {
|
||||
await prepare();
|
||||
await createNote();
|
||||
await lockNote();
|
||||
await removeFromVault();
|
||||
});
|
||||
});
|
||||
143
apps/mobile/e2e/tests/vault.e2e.ts
Normal file
143
apps/mobile/e2e/tests/vault.e2e.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { expect } from "detox";
|
||||
import { notesnook } from "../test.ids";
|
||||
import { Tests } from "./utils";
|
||||
|
||||
async function lockNote() {
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromId("icon-lock-unlock").waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromText("Lock").isVisible();
|
||||
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText("1234");
|
||||
await Tests.fromId(notesnook.ids.dialogs.vault.pwdAlt).element.typeText(
|
||||
"1234"
|
||||
);
|
||||
await Tests.fromText("Lock").waitAndTap();
|
||||
await Tests.fromId("note-locked-icon").isVisible();
|
||||
}
|
||||
|
||||
async function removeFromVault() {
|
||||
await Tests.fromId(notesnook.listitem.menu).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromId("icon-lock-unlock").waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText("1234");
|
||||
await Tests.fromText("Unlock").waitAndTap();
|
||||
await Tests.fromId("note-locked-icon").isNotVisible();
|
||||
}
|
||||
|
||||
async function openLockedNote(pwd?: string) {
|
||||
await Tests.fromId(notesnook.ids.note.get(0)).waitAndTap();
|
||||
await Tests.sleep(500);
|
||||
await web()
|
||||
.element(by.web.name("password"))
|
||||
.typeText(pwd || "1234", false);
|
||||
await web().element(by.web.className("unlock-note")).tap();
|
||||
await Tests.sleep(500);
|
||||
await expect(web().element(by.web.className("unlock-note"))).not.toExist();
|
||||
}
|
||||
|
||||
async function goToPrivacySecuritySettings() {
|
||||
await Tests.navigate("Settings");
|
||||
await Tests.fromText("Vault").waitAndTap();
|
||||
}
|
||||
|
||||
describe("VAULT", () => {
|
||||
it("Create vault from settings", async () => {
|
||||
await Tests.prepare();
|
||||
await goToPrivacySecuritySettings();
|
||||
await Tests.fromText("Create vault").waitAndTap();
|
||||
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText(
|
||||
"1234"
|
||||
);
|
||||
await Tests.fromId(notesnook.ids.dialogs.vault.pwdAlt).element.typeText(
|
||||
"1234"
|
||||
);
|
||||
await Tests.fromText("Create").waitAndTap();
|
||||
await Tests.fromText("Clear vault").isVisible();
|
||||
});
|
||||
|
||||
it("Change vault password", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await lockNote();
|
||||
await goToPrivacySecuritySettings();
|
||||
await Tests.fromText("Change vault password").waitAndTap();
|
||||
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText(
|
||||
"1234"
|
||||
);
|
||||
await Tests.fromId(notesnook.ids.dialogs.vault.changePwd).element.typeText(
|
||||
"2362"
|
||||
);
|
||||
await Tests.fromText("Change").waitAndTap();
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await Tests.sleep(500);
|
||||
await openLockedNote("2362");
|
||||
});
|
||||
|
||||
it("Delete vault", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await lockNote();
|
||||
await goToPrivacySecuritySettings();
|
||||
await Tests.fromText("Delete vault").waitAndTap();
|
||||
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText(
|
||||
"1234"
|
||||
);
|
||||
await Tests.fromText("Delete").waitAndTap();
|
||||
await Tests.fromText("Create vault").isVisible();
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await Tests.fromId(notesnook.listitem.menu).isVisible();
|
||||
});
|
||||
|
||||
it("Delete vault with locked notes", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await lockNote();
|
||||
await goToPrivacySecuritySettings();
|
||||
await Tests.fromText("Delete vault").waitAndTap();
|
||||
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText(
|
||||
"1234"
|
||||
);
|
||||
await Tests.fromText("Delete notes in this vault").waitAndTap();
|
||||
await Tests.fromText("Delete").waitAndTap();
|
||||
await Tests.fromText("Create vault").isVisible();
|
||||
await device.pressBack();
|
||||
await device.pressBack();
|
||||
await Tests.fromId(notesnook.listitem.menu).isNotVisible();
|
||||
});
|
||||
|
||||
it("Add a note to vault", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await lockNote();
|
||||
await openLockedNote();
|
||||
});
|
||||
|
||||
it.only("Remove note from vault", async () => {
|
||||
await Tests.prepare();
|
||||
await Tests.createNote();
|
||||
await lockNote();
|
||||
await removeFromVault();
|
||||
});
|
||||
});
|
||||
@@ -52,7 +52,7 @@ module.exports = {
|
||||
emulator: {
|
||||
type: 'android.emulator',
|
||||
device: {
|
||||
avdName: 'Pixel_5_API_31'
|
||||
avdName: 'Pixel_5_API_34'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ammarahmed/notifee-react-native": "7.4.7",
|
||||
"@ammarahmed/react-native-share-extension": "^3.0.0",
|
||||
"@ammarahmed/react-native-sodium": "1.5.4",
|
||||
"@bam.tech/react-native-image-resizer": "3.0.5",
|
||||
"@callstack/repack": "^4.1.1",
|
||||
"@react-native-clipboard/clipboard": "^1.9.0",
|
||||
@@ -73,7 +71,10 @@
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
"react-native-screenguard": "^1.0.0",
|
||||
"@formatjs/intl-locale": "4.0.0",
|
||||
"@formatjs/intl-pluralrules": "5.2.14"
|
||||
"@formatjs/intl-pluralrules": "5.2.14",
|
||||
"detox": "^20.27.6",
|
||||
"@ammarahmed/react-native-share-extension": "^2.6.0",
|
||||
"@ammarahmed/react-native-sodium": "1.5.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
@@ -86,7 +87,6 @@
|
||||
"@react-native/metro-config": "0.74.86",
|
||||
"@tsconfig/react-native": "^3.0.2",
|
||||
"@types/html-to-text": "^8.0.1",
|
||||
"@types/jest": "^29.2.1",
|
||||
"@types/metro-config": "^0.76.3",
|
||||
"@types/react": "^18.2.6",
|
||||
"@types/react-native": "^0.69.1",
|
||||
@@ -98,19 +98,13 @@
|
||||
"babel-loader": "^8.2.5",
|
||||
"babel-plugin-module-resolver": "^4.1.0",
|
||||
"babel-plugin-transform-remove-console": "6.9.4",
|
||||
"detox": "^20.11.2",
|
||||
"eslint": "^8.19.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"eslint-plugin-react-native": "^4.0.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"expect": "^29.6.2",
|
||||
"jest": "^29.6.3",
|
||||
"jest-circus": "^29.6.2",
|
||||
"jest-image-snapshot": "^6.2.0",
|
||||
"@react-native/babel-preset": "0.74.86",
|
||||
"pixelmatch": "^5.3.0",
|
||||
"prettier": "2.8.8",
|
||||
"react-native-actions-shortcuts": "^1.0.1",
|
||||
"react-native-bundle-visualizer": "^3.1.1",
|
||||
@@ -118,10 +112,16 @@
|
||||
"react-refresh": "0.14.0",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"terser-webpack-plugin": "^5.3.5",
|
||||
"ts-jest": "^29.1.1",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack": "^5.88.2",
|
||||
"metro-react-native-babel-preset": "0.77.0",
|
||||
"acorn-import-attributes": "1.9.5"
|
||||
"acorn-import-attributes": "1.9.5",
|
||||
"expect": "^29.7.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-circus": "^29.7.0",
|
||||
"jest-image-snapshot": "^6.4.0",
|
||||
"ts-jest": "^29.2.5",
|
||||
"pixelmatch": "^6.0.0",
|
||||
"@types/jest": "^29.5.14"
|
||||
}
|
||||
}
|
||||
|
||||
515
apps/mobile/package-lock.json
generated
515
apps/mobile/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
diff --git a/node_modules/react-native-actions-shortcuts/android/build.gradle b/node_modules/react-native-actions-shortcuts/android/build.gradle
|
||||
index 19bd311..d15cdaf 100644
|
||||
index 19bd311..bc37238 100644
|
||||
--- a/node_modules/react-native-actions-shortcuts/android/build.gradle
|
||||
+++ b/node_modules/react-native-actions-shortcuts/android/build.gradle
|
||||
@@ -29,7 +29,7 @@ android {
|
||||
@@ -7,7 +7,7 @@ index 19bd311..d15cdaf 100644
|
||||
buildToolsVersion getExtOrDefault('buildToolsVersion')
|
||||
defaultConfig {
|
||||
- minSdkVersion 16
|
||||
+ minSdkVersion 21
|
||||
+ minSdkVersion getExtOrDefault('minSdkVersion')
|
||||
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
diff --git a/node_modules/react-native-fingerprint-scanner/android/build.gradle b/node_modules/react-native-fingerprint-scanner/android/build.gradle
|
||||
index eaf3829..6c392ba 100644
|
||||
--- a/node_modules/react-native-fingerprint-scanner/android/build.gradle
|
||||
+++ b/node_modules/react-native-fingerprint-scanner/android/build.gradle
|
||||
@@ -49,5 +49,5 @@ dependencies {
|
||||
// 1.2.3 is the minimum version compatible with androidx.
|
||||
// See https://github.com/uccmawei/FingerprintIdentify/issues/74
|
||||
// (translation https://translate.google.com/translate?sl=zh-CN&tl=en&u=https://github.com/uccmawei/FingerprintIdentify/issues/74)
|
||||
- implementation "com.wei.android.lib:fingerprintidentify:${safeExtGet("fingerprintidentify", "1.2.6")}"
|
||||
+ implementation "com.github.uccmawei:FingerprintIdentify:1.2.6"
|
||||
}
|
||||
@@ -39,7 +39,7 @@ index 0ccfd23..7771e6f 100644
|
||||
s.preserve_paths = 'LICENSE', 'package.json'
|
||||
s.source_files = '**/*.{h,m}'
|
||||
diff --git a/node_modules/react-native-tooltips/android/build.gradle b/node_modules/react-native-tooltips/android/build.gradle
|
||||
index 978045f..401b458 100644
|
||||
index 978045f..59c64f1 100644
|
||||
--- a/node_modules/react-native-tooltips/android/build.gradle
|
||||
+++ b/node_modules/react-native-tooltips/android/build.gradle
|
||||
@@ -3,8 +3,9 @@ buildscript {
|
||||
@@ -53,24 +53,36 @@ index 978045f..401b458 100644
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -15,12 +16,12 @@ buildscript {
|
||||
@@ -14,18 +15,19 @@ buildscript {
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
-android {
|
||||
- compileSdkVersion 29
|
||||
- buildToolsVersion '29.0.2'
|
||||
+ compileSdkVersion 31
|
||||
+ buildToolsVersion '31.0.0'
|
||||
|
||||
+def safeExtGet(prop, fallback) {
|
||||
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
||||
+}
|
||||
+
|
||||
+android {
|
||||
+ compileSdkVersion safeExtGet('compileSdkVersion', 29)
|
||||
+ buildToolsVersion safeExtGet('buildToolsVersion', '29.0.2')
|
||||
defaultConfig {
|
||||
- minSdkVersion 16
|
||||
- targetSdkVersion 29
|
||||
+ minSdkVersion 21
|
||||
+ targetSdkVersion 31
|
||||
+ minSdkVersion safeExtGet('minSdkVersion', 21)
|
||||
+ targetSdkVersion safeExtGet('targetSdkVersion', 29)
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
- versionName "1.0"
|
||||
- }
|
||||
- lintOptions {
|
||||
- abortOnError false
|
||||
+ versionName "0.1"
|
||||
}
|
||||
@@ -36,5 +37,5 @@ repositories {
|
||||
}
|
||||
|
||||
@@ -36,5 +38,5 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation 'com.facebook.react:react-native:+'
|
||||
@@ -104,7 +116,7 @@ index fb96466..75a6fdb 100644
|
||||
|
||||
@interface TooltipDelegate : NSObject <SexyTooltipDelegate>
|
||||
|
||||
@@ -7,9 +9,15 @@ @interface TooltipDelegate : NSObject <SexyTooltipDelegate>
|
||||
@@ -7,9 +9,15 @@
|
||||
@end
|
||||
|
||||
@implementation TooltipDelegate
|
||||
@@ -120,7 +132,7 @@ index fb96466..75a6fdb 100644
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -17,77 +25,120 @@ - (void)tooltipDidDismiss:(SexyTooltip *)tooltip {
|
||||
@@ -17,77 +25,120 @@
|
||||
|
||||
@implementation RNTooltips
|
||||
|
||||
|
||||
@@ -646,6 +646,7 @@ const Tiptap = ({
|
||||
/>
|
||||
|
||||
<button
|
||||
className="unlock-note"
|
||||
style={{
|
||||
backgroundColor: colors.primary.accent,
|
||||
borderRadius: 5,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -424,12 +424,11 @@ $headline$: Use starting line of the note as title.`,
|
||||
other: ""
|
||||
}),
|
||||
|
||||
createVault: () => t`Create Vault`,
|
||||
createVaultDesc: () =>
|
||||
t`A vault stores your notes in a password-encrypted storage.`,
|
||||
vaultFingerprintUnlock: () => t`Vault Fingerprint Unlock`,
|
||||
revokeVaultFingerprintUnlock: () => t`Revoke Vault Fingerprint Unlock`,
|
||||
changeVaultPassword: () => t`Change Vault Password`,
|
||||
createVault: () => t`Create vault`,
|
||||
createVaultDesc: () => t`A vault stores your notes in a encrypted storage.`,
|
||||
vaultFingerprintUnlock: () => t`Vault fingerprint unlock`,
|
||||
revokeVaultFingerprintUnlock: () => t`Revoke vault fingerprint unlock`,
|
||||
changeVaultPassword: () => t`Change vault password`,
|
||||
deleteNote: () => doActions.delete.note(1),
|
||||
shareNote: () => t`Share note`,
|
||||
copyNote: () => t`Copy note`,
|
||||
|
||||
Reference in New Issue
Block a user