Merge branch 'master' into beta

This commit is contained in:
Ammar Ahmed
2025-10-06 12:42:59 +05:00
18 changed files with 563 additions and 546 deletions

View File

@@ -19,14 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { strings } from "@notesnook/intl";
import { useThemeColors } from "@notesnook/theme";
import { useRoute } from "@react-navigation/native";
import React, { useEffect, useState } from "react";
import {
ScrollView,
TouchableOpacity,
View,
useWindowDimensions
} from "react-native";
import { TouchableOpacity, View, useWindowDimensions } from "react-native";
import { SheetManager } from "react-native-actions-sheet";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import { DDS } from "../../services/device-detection";
import { eSendEvent } from "../../services/event-manager";
import Navigation from "../../services/navigation";
@@ -47,8 +44,7 @@ import { hideAuth } from "./common";
import { ForgotPassword } from "./forgot-password";
import { AuthHeader } from "./header";
import { useLogin } from "./use-login";
import { useRoute } from "@react-navigation/native";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import SettingsService from "../../services/settings";
const LoginSteps = {
emailAuth: 1,
@@ -81,7 +77,7 @@ export const Login = ({ changeMode }) => {
}
}, 5000);
if (!PremiumService.get()) {
if (!PremiumService.get() && !SettingsService.getProperty("serverUrls")) {
Navigation.navigate("PayWall", {
context: "signup",
state: route.params.state,

View File

@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { strings } from "@notesnook/intl";
import { useThemeColors } from "@notesnook/theme";
import { useRoute } from "@react-navigation/native";
import React, { useRef, useState } from "react";
import { TouchableOpacity, View, useWindowDimensions } from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
@@ -38,7 +39,6 @@ import Heading from "../ui/typography/heading";
import Paragraph from "../ui/typography/paragraph";
import { AuthHeader } from "./header";
import { SignupContext } from "./signup-context";
import { useRoute } from "@react-navigation/native";
const SignupSteps = {
signup: 0,
@@ -91,11 +91,13 @@ export const Signup = ({ changeMode, welcome }) => {
setLastSynced(await db.lastSynced());
clearMessage();
setEmailVerifyMessage();
Navigation.navigate("PayWall", {
canGoBack: false,
state: route.params.state,
context: "signup"
});
if (!SettingsService.getProperty("serverUrls")) {
Navigation.navigate("PayWall", {
canGoBack: false,
state: route.params.state,
context: "signup"
});
}
return true;
} catch (e) {
setCurrentStep(SignupSteps.signup);

View File

@@ -60,6 +60,7 @@ import usePricingPlans, {
PricingPlan
} from "../../hooks/use-pricing-plans";
import Navigation, { NavigationProps } from "../../services/navigation";
import PremiumService from "../../services/premium";
import { getElevationStyle } from "../../utils/elevation";
import { openLinkInBrowser } from "../../utils/functions";
import { AppFontSize, defaultBorderRadius } from "../../utils/size";
@@ -74,7 +75,6 @@ import { IconButton } from "../ui/icon-button";
import { SvgView } from "../ui/svg";
import Heading from "../ui/typography/heading";
import Paragraph from "../ui/typography/paragraph";
import PremiumService from "../../services/premium";
const Steps = {
select: 1,
@@ -114,15 +114,8 @@ const PayWall = (props: NavigationProps<"PayWall">) => {
routeParams.state?.planId,
routeParams.state?.productId
);
console.log(
"selectPlan",
routeParams.state?.planId,
routeParams.state?.productId,
(pricingPlans.selectedProduct as any).productId
);
}
setStep(Steps.buy);
console.log("Buy step");
}
}, [routeParams.state]);
@@ -949,7 +942,6 @@ const PricingPlanCard = ({
regionalDiscount?.sku ||
`notesnook.${plan.id}.${annualBilling ? "yearly" : "monthly"}`
];
console.log(regionalDiscount?.sku);
const price = pricingPlans?.getPrice(
product as RNIap.Subscription,
pricingPlans.hasTrialOffer(plan.id, product?.productId) ? 1 : 0,
@@ -962,6 +954,7 @@ const PricingPlanCard = ({
);
useEffect(() => {
if (pricingPlans?.isGithubRelease) return;
pricingPlans
?.getRegionalDiscount(
plan.id,
@@ -980,7 +973,7 @@ const PricingPlanCard = ({
pricingPlans.isSubscribed();
const isNotReady =
pricingPlans?.loadingPlans || (!price && !WebPlan?.price.gross);
pricingPlans?.loadingPlans || (!price && !WebPlan?.price?.gross);
return (
<TouchableOpacity
@@ -1112,7 +1105,7 @@ const PricingPlanCard = ({
</View>
</View>
{pricingPlans?.loadingPlans || (!price && !WebPlan?.price.gross) ? (
{pricingPlans?.loadingPlans || (!price && !WebPlan?.price?.gross) ? (
<ActivityIndicator size="small" color={colors.primary.accent} />
) : (
<View>
@@ -1120,7 +1113,7 @@ const PricingPlanCard = ({
{isFreePlan
? "0.00"
: price ||
`${WebPlan?.price.currency} ${WebPlan?.price.gross}`}{" "}
`${WebPlan?.price?.currency} ${WebPlan?.price?.gross}`}{" "}
<Paragraph>/{strings.month()}</Paragraph>
</Paragraph>

View File

@@ -15,6 +15,7 @@ import {
} from "../../../services/event-manager";
import Navigation from "../../../services/navigation";
import PremiumService from "../../../services/premium";
import SettingsService from "../../../services/settings";
import { useUserStore } from "../../../stores/use-user-store";
import { eCloseSheet } from "../../../utils/events";
import { AppFontSize } from "../../../utils/size";
@@ -37,7 +38,6 @@ export default function PaywallSheet<Tid extends FeatureId>(props: {
const { colors } = useThemeColors();
const pricingPlans = usePricingPlans();
useEffect(() => {
console.log("PaywallSheet mounted with feature:", props.feature);
ToastManager.hide();
if (!props.feature.availableOn) return;
const plan = pricingPlans.pricingPlans.find(
@@ -55,11 +55,11 @@ export default function PaywallSheet<Tid extends FeatureId>(props: {
}, []);
const isSubscribedOnWeb =
(PremiumService.get() &&
PremiumService.get() &&
(pricingPlans.user?.subscription?.provider ===
SubscriptionProvider.PADDLE ||
pricingPlans.user?.subscription?.provider ===
SubscriptionProvider.PADDLE) ||
pricingPlans.user?.subscription?.provider ===
SubscriptionProvider.STREETWRITERS;
SubscriptionProvider.STREETWRITERS);
const isCurrentPlatform =
(pricingPlans.user?.subscription?.provider === SubscriptionProvider.APPLE &&
@@ -194,25 +194,28 @@ export default function PaywallSheet<Tid extends FeatureId>(props: {
width: "100%"
}}
onPress={() => {
if (
pricingPlans.user?.subscription.plan ===
SubscriptionPlan.LEGACY_PRO ||
!isCurrentPlatform
) {
ToastManager.show({
message: strings.cannotChangePlan(),
context: "local"
});
return;
if (PremiumService.get()) {
if (
pricingPlans.user?.subscription.plan ===
SubscriptionPlan.LEGACY_PRO ||
!isCurrentPlatform
) {
ToastManager.show({
message: strings.cannotChangePlan(),
context: "local"
});
return;
}
if (isSubscribedOnWeb) {
ToastManager.show({
message: strings.changePlanOnWeb(),
context: "local"
});
return;
}
}
if (isSubscribedOnWeb) {
ToastManager.show({
message: strings.changePlanOnWeb(),
context: "local"
});
return;
}
eSendEvent(eCloseSheet);
if (!useUserStore.getState().user) {
Navigation.navigate("Auth", {
@@ -256,6 +259,7 @@ export default function PaywallSheet<Tid extends FeatureId>(props: {
}
PaywallSheet.present = <Tid extends FeatureId>(feature: FeatureResult<Tid>) => {
if (SettingsService.getProperty("serverUrls")) return;
presentSheet({
component: <PaywallSheet feature={feature} />
});

View File

@@ -20,6 +20,7 @@ import Paragraph from "../../ui/typography/paragraph";
import { SubscriptionPlan, SubscriptionProvider } from "@notesnook/core";
import { useUserStore } from "../../../stores/use-user-store";
import PremiumService from "../../../services/premium";
import SettingsService from "../../../services/settings";
export function PlanLimits() {
const { colors } = useThemeColors();
@@ -84,10 +85,11 @@ export function PlanLimits() {
</View>
))}
{(user?.subscription?.provider === SubscriptionProvider.PADDLE ||
{((user?.subscription?.provider === SubscriptionProvider.PADDLE ||
user?.subscription?.provider === SubscriptionProvider.STREETWRITERS ||
!isCurrentPlatform) &&
PremiumService.get() ? null : (
PremiumService.get()) ||
SettingsService.getProperty("serverUrls") ? null : (
<Button
title={strings.changePlan()}
onPress={() => {

View File

@@ -24,10 +24,11 @@ import { FlatList, View } from "react-native";
import { DraxProvider, DraxScrollView } from "react-native-drax";
import { db } from "../../common/database";
import Navigation from "../../services/navigation";
import SettingsService from "../../services/settings";
import { useMenuStore } from "../../stores/use-menu-store";
import { useSettingStore } from "../../stores/use-setting-store";
import { useUserStore } from "../../stores/use-user-store";
import { SUBSCRIPTION_STATUS } from "../../utils/constants";
import { MenuItemsList } from "../../utils/menu-items";
import { DefaultAppStyles } from "../../utils/styles";
import ReorderableList from "../list/reorderable-list";
import { MenuItemProperties } from "../sheets/menu-item-properties";
@@ -36,7 +37,6 @@ import { ColorSection } from "./color-section";
import { MenuItem } from "./menu-item";
import { PinnedSection } from "./pinned-section";
import { SideMenuHeader } from "./side-menu-header";
import { MenuItemsList } from "../../utils/menu-items";
const pro = {
title: strings.upgradePlan(),
@@ -140,9 +140,10 @@ export function SideMenuHome() {
paddingVertical: DefaultAppStyles.GAP_VERTICAL
}}
>
{subscriptionType === SubscriptionPlan.FREE ||
!subscriptionType ||
!user ? (
{(subscriptionType === SubscriptionPlan.FREE ||
!subscriptionType ||
!user) &&
!SettingsService.getProperty("serverUrls") ? (
<Button
title={pro.title}
style={{

View File

@@ -85,6 +85,7 @@ export default function useFeatureManager() {
negativeText: strings.cancel(),
positivePress: async () => {
eSendEvent(eCloseSimpleDialog);
if (SettingsService.getProperty("serverUrls")) return;
Navigation.navigate("PayWall", {
context: "logged-in"
});

View File

@@ -25,6 +25,7 @@ import { DatabaseLogger, db } from "../common/database";
import PremiumService from "../services/premium";
import { useSettingStore } from "../stores/use-setting-store";
import { useUserStore } from "../stores/use-user-store";
import SettingsService from "../services/settings";
function numberWithCommas(x: string) {
const parts = x.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
@@ -201,7 +202,7 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
if (productId?.includes("5year")) return false;
if (isGithubRelease) {
if (
user?.subscription.trialsAvailed?.some(
user?.subscription?.trialsAvailed?.some(
(plan) => plan === planIdToIndex(planId || currentPlan)
)
) {
@@ -246,7 +247,10 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
});
setPlans([...pricingPlans]);
setUserCanRequestTrial(hasTrialOffer());
if (Config.GITHUB_RELEASE === "true") {
if (
Config.GITHUB_RELEASE === "true" &&
!SettingsService.getProperty("serverUrls")
) {
try {
const products = WebPlanCache || (await db.pricing.products());
WebPlanCache = products;
@@ -264,7 +268,8 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
if (!product) return;
if (Platform.OS === "android") {
if (isGithubRelease)
if (isGithubRelease) {
if (!(product as Plan)?.price) return null;
return `${(product as Plan).price.currency} ${
(product as Plan).period === "yearly"
? ((product as Plan).price.gross / 12).toFixed(2)
@@ -272,6 +277,7 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
? ((product as Plan).price.gross / (12 * 5)).toFixed(2)
: (product as Plan).price.gross
}`;
}
const pricingPhaseListItem =
(product as RNIap.SubscriptionAndroid)?.subscriptionOfferDetails?.[0]
@@ -414,7 +420,7 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
offerIndex: number
) => {
if (isGithubRelease) {
return (product as Plan).period;
return (product as Plan)?.period;
}
if (Platform.OS === "android") {
@@ -444,7 +450,7 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
if (isGithubRelease) {
return {
duration: 1,
type: (product as Plan).period
type: (product as Plan)?.period
};
}
@@ -591,7 +597,8 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
) => {
if (!product) return null;
if (isGithubRelease)
if (isGithubRelease) {
if (!(product as Plan)?.price) return null;
return `${(product as Plan).price.currency} ${
(product as Plan).period === "yearly"
? ((product as Plan).price.gross / 12).toFixed(2)
@@ -599,6 +606,7 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
? ((product as Plan).price.gross / (12 * 5)).toFixed(2)
: (product as Plan).price.gross
}`;
}
const androidPricingPhase = (product as RNIap.SubscriptionAndroid)
?.subscriptionOfferDetails?.[0].pricingPhases?.pricingPhaseList?.[

View File

@@ -43,6 +43,7 @@ import { planToDisplayName } from "../../utils/constants";
import { AppFontSize } from "../../utils/size";
import { DefaultAppStyles } from "../../utils/styles";
import { SectionItem } from "./section-item";
import SettingsService from "../../services/settings";
export const getTimeLeft = (t2) => {
let daysRemaining = dayjs(t2).diff(dayjs(), "days");
@@ -339,11 +340,13 @@ const SettingsUserSection = ({ item }) => {
</Paragraph>
</TouchableOpacity>
{(user.subscription?.provider === SubscriptionProvider.PADDLE ||
{((user.subscription?.provider ===
SubscriptionProvider.PADDLE ||
user.subscription?.provider ===
SubscriptionProvider.STREETWRITERS ||
!isCurrentPlatform) &&
PremiumService.get() ? null : (
PremiumService.get()) ||
SettingsService.getProperty("serverUrls") ? null : (
<Button
title={
user.subscription?.plan !== SubscriptionPlan.FREE

View File

@@ -71,6 +71,7 @@ export function planToDisplayName(plan: SubscriptionPlan): string {
return strings.freePlan();
case SubscriptionPlan.ESSENTIAL:
return strings.essentialPlan();
case SubscriptionPlan.LEGACY_PRO:
case SubscriptionPlan.PRO:
return strings.proPlan();
case SubscriptionPlan.BELIEVER:

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { authenticator } from "otplib";
import { Tests } from "./utils";
import { TestBuilder } from "./utils";
import dotenv from "dotenv";
import path from "path";
@@ -34,20 +34,6 @@ const USER = {
}
};
async function login() {
await Tests.fromText("Login to encrypt and sync notes").tap();
await Tests.fromId("input.email").element.typeText(USER.login.email!);
await Tests.fromText("Continue").tap();
await Tests.sleep(3000);
await Tests.fromId("input.totp").element.typeText(
authenticator.generate(USER.login.totpSecret!)
);
await Tests.fromText("Next").tap();
await Tests.sleep(3000);
await Tests.fromId("input.password").element.typeText(USER.login.password!);
await Tests.fromId("input.password").element.tapReturnKey();
}
// async function deleteAccount() {
// await tapByText("Account Settings");
// await sleep(2000);
@@ -67,11 +53,27 @@ async function login() {
// await elementById("input.confirmPassword").tapReturnKey();
// }
async function login() {
await TestBuilder.create()
.waitAndTapByText("Login to encrypt and sync notes")
.typeTextById("input.email", USER.login.email!)
.tapReturnKeyById("input.email")
.wait(3000)
.typeTextById("input.totp", authenticator.generate(USER.login.totpSecret!))
.waitAndTapByText("Next")
.wait(3000)
.typeTextById("input.password", USER.login.password!)
.tapReturnKeyById("input.password")
.run();
}
describe("AUTH", () => {
it("Login", async () => {
await Tests.prepare();
await login();
await Tests.sleep(10000);
await Tests.fromText("Login to encrypt and sync notes").isNotVisible();
await TestBuilder.create()
.prepare()
.addStep(login)
.wait(3000)
.isNotVisibleByText("Notesnook Plans")
.run();
});
});

View File

@@ -18,266 +18,209 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { notesnook } from "../test.ids";
import { Tests } from "./utils";
import { TestBuilder } from "./utils";
describe("NOTEBOOKS", () => {
it("Create a notebook with title only", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook("Notebook 1", false);
await Tests.sleep(500);
await Tests.fromText("Notebook 1").isVisible();
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-notebooks")
.waitAndTapById("sidebar-add-button")
.createNotebook("Notebook 1", false)
.wait(500)
.isVisibleByText("Notebook 1")
.run();
});
it("Create a notebook title & description", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook("Notebook 1", true);
await Tests.sleep(500);
await Tests.fromText("Notebook 1").isVisible();
it("Create a notebook with title & description", async () => {
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-notebooks")
.waitAndTapById("sidebar-add-button")
.createNotebook("Notebook 1", true)
.wait(500)
.isVisibleByText("Notebook 1")
.run();
});
it("Add a sub notebook to a notebook", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook("Notebook 1", true);
await Tests.sleep(500);
await Tests.fromText("Notebook 1").element.longPress();
await Tests.sleep(500);
await Tests.fromText("Add notebook").waitAndTap();
await Tests.createNotebook("Sub notebook", true);
await Tests.sleep(500);
await Tests.fromId("expand-notebook-0").waitAndTap();
await Tests.fromText("Sub notebook").isVisible();
await Tests.fromText("Sub notebook").element.longPress();
await Tests.sleep(500);
await Tests.fromText("Move to trash").waitAndTap();
await Tests.fromText("Delete").waitAndTap();
await Tests.fromText("Sub notebook").isNotVisible();
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-notebooks")
.waitAndTapById("sidebar-add-button")
.createNotebook("Notebook 1", true)
.wait(500)
.longPressByText("Notebook 1")
.wait(500)
.waitAndTapByText("Add notebook")
.createNotebook("Sub notebook", true)
.wait(500)
.waitAndTapById("expand-notebook-0")
.isVisibleByText("Sub notebook")
.longPressByText("Sub notebook")
.wait(500)
.waitAndTapByText("Move to trash")
.waitAndTapByText("Delete")
.isNotVisibleByText("Sub notebook")
.run();
});
it("Edit notebook", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook("Notebook 1", true);
await Tests.sleep(500);
await Tests.fromText("Notebook 1").element.longPress();
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("Notebook 1 (edited)").isVisible();
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-notebooks")
.waitAndTapById("sidebar-add-button")
.createNotebook("Notebook 1", true)
.wait(500)
.longPressByText("Notebook 1")
.wait(500)
.waitAndTapByText("Edit notebook")
.typeTextById(notesnook.ids.dialogs.notebook.inputs.title, " (edited)")
.waitAndTapByText("Save")
.isVisibleByText("Notebook 1 (edited)")
.run();
});
it("Edit a sub notebook", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook("Notebook 1", true);
await Tests.sleep(500);
await Tests.fromText("Notebook 1").element.longPress();
await Tests.sleep(500);
await Tests.fromText("Add notebook").waitAndTap();
await Tests.createNotebook("Sub notebook", true);
await Tests.sleep(500);
await Tests.fromId("expand-notebook-0").waitAndTap();
await Tests.fromText("Sub notebook").element.longPress();
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();
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-notebooks")
.waitAndTapById("sidebar-add-button")
.createNotebook("Notebook 1", true)
.wait(500)
.longPressByText("Notebook 1")
.wait(500)
.waitAndTapByText("Add notebook")
.createNotebook("Sub notebook", true)
.wait(500)
.waitAndTapById("expand-notebook-0")
.longPressByText("Sub notebook")
.wait(500)
.waitAndTapByText("Edit notebook")
.typeTextById(notesnook.ids.dialogs.notebook.inputs.title, " (edited)")
.waitAndTapByText("Save")
.isVisibleByText("Sub notebook (edited)")
.run();
});
it("Add a note to notebook", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook("Notebook 1", true);
await Tests.sleep(500);
await Tests.fromText("Notebook 1").waitAndTap();
await Tests.createNote();
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-notebooks")
.waitAndTapById("sidebar-add-button")
.createNotebook("Notebook 1", true)
.wait(500)
.waitAndTapByText("Notebook 1")
.createNote()
.run();
});
it("Remove note from Notebook", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook("Notebook 1", true);
await Tests.sleep(500);
await Tests.fromText("Notebook 1").waitAndTap();
await Tests.sleep(500);
let note = await Tests.createNote();
await Tests.fromText(note.body).element.longPress();
await Tests.sleep(500);
await Tests.fromId("select-minus").waitAndTap();
await Tests.fromId(note.title).isNotVisible();
it.only("Remove note from notebook", async () => {
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-notebooks")
.waitAndTapById("sidebar-add-button")
.createNotebook("Notebook 1", true)
.wait(500)
.waitAndTapByText("Notebook 1")
.wait(500)
.createNote()
.saveResult()
.processResult(async (note) => {
await TestBuilder.create()
.longPressByText(note.body)
.wait(500)
.waitAndTapById("select-minus")
.isNotVisibleById(note.title)
.run();
})
.run();
});
it("Add/Remove note to notebook from home", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook("Notebook 1", true);
await Tests.sleep(500);
await Tests.fromId("tab-home").waitAndTap();
await Tests.fromText("Notes").waitAndTap();
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.fromId("floating-save-button").waitAndTap();
await Tests.fromText("Notebook 1").isVisible();
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-notebooks")
.waitAndTapById("sidebar-add-button")
.createNotebook("Notebook 1", true)
.wait(500)
.waitAndTapById("tab-home")
.waitAndTapByText("Notes")
.createNote()
.waitAndTapById(notesnook.listitem.menu)
.wait(500)
.waitAndTapById("icon-notebooks")
.waitAndTapByText("Notebook 1")
.waitAndTapById("floating-save-button")
.isVisibleByText("Notebook 1")
.run();
});
it("Edit notebook title, description", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook();
await Tests.sleep(500);
await Tests.fromText("Notebook 1").isVisible();
await Tests.fromText("Notebook 1").element.longPress();
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();
it("Edit notebook title and description", async () => {
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-notebooks")
.waitAndTapById("sidebar-add-button")
.createNotebook()
.wait(500)
.isVisibleByText("Notebook 1")
.longPressByText("Notebook 1")
.wait(500)
.waitAndTapByText("Edit notebook")
.typeTextById(notesnook.ids.dialogs.notebook.inputs.title, " (Edited)")
.clearTextById(notesnook.ids.dialogs.notebook.inputs.description)
.typeTextById(
notesnook.ids.dialogs.notebook.inputs.description,
"Description of Notebook 1 (Edited)"
)
.waitAndTapByText("Save")
.isVisibleByText("Notebook 1 (Edited)")
.run();
});
it("Move notebook to trash", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook("Notebook 1", false);
await Tests.sleep(500);
await Tests.fromText("Notebook 1").isVisible();
await Tests.fromText("Notebook 1").element.longPress();
await Tests.sleep(500);
await Tests.fromText("Move to trash").waitAndTap();
await Tests.fromText("Delete").waitAndTap();
await Tests.fromId("tab-home").waitAndTap();
await Tests.fromText("Trash").waitAndTap();
await Tests.fromText("Notebook 1").isVisible();
});
it.skip("Move notebook to trash with notes", async () => {
await Tests.prepare();
let note = await Tests.createNote();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook("Notebook 1", false);
await device.pressBack();
await Tests.fromId(notesnook.ids.note.get(0)).element.longPress();
await Tests.sleep(500);
await Tests.fromId("select-plus").waitAndTap();
await Tests.fromText("Notebook 1").isVisible();
await Tests.fromText("Notebook 1").waitAndTap();
await Tests.fromId("floating-save-button").waitAndTap();
await Tests.sleep(500);
await Tests.openSideMenu();
await Tests.fromId("tab-home").waitAndTap();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.sleep(500);
await Tests.fromText("Notebook 1").isVisible();
await Tests.fromText("Notebook 1").element.longPress();
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.sleep(500);
await Tests.fromId("tab-home").waitAndTap();
await Tests.fromText("Trash").waitAndTap();
await Tests.fromText("Notebook 1").isVisible();
await Tests.fromText(note.body).isVisible();
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-notebooks")
.waitAndTapById("sidebar-add-button")
.createNotebook("Notebook 1", false)
.wait(500)
.isVisibleByText("Notebook 1")
.longPressByText("Notebook 1")
.wait(500)
.waitAndTapByText("Move to trash")
.waitAndTapByText("Delete")
.waitAndTapById("tab-home")
.waitAndTapByText("Trash")
.isVisibleByText("Notebook 1")
.run();
});
it("Pin notebook to side menu", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-notebooks").waitAndTap();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.createNotebook("Notebook 1", false);
await Tests.sleep(500);
await Tests.fromText("Notebook 1").isVisible();
await Tests.fromText("Notebook 1").element.longPress();
await Tests.sleep(500);
await Tests.fromId("icon-add-shortcut").waitAndTap();
await Tests.sleep(500);
await Tests.fromId("tab-home").waitAndTap();
await Tests.fromText("Notebook 1").isVisible();
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-notebooks")
.waitAndTapById("sidebar-add-button")
.createNotebook("Notebook 1", false)
.wait(500)
.isVisibleByText("Notebook 1")
.longPressByText("Notebook 1")
.wait(500)
.waitAndTapById("icon-add-shortcut")
.wait(500)
.waitAndTapById("tab-home")
.isVisibleByText("Notebook 1")
.run();
});
});

View File

@@ -17,15 +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 { Tests } from "./utils";
import { TestBuilder } from "./utils";
describe("Search", () => {
it("Search for a note", async () => {
await Tests.prepare();
let note = await Tests.createNote();
await Tests.fromId("search-header").waitAndTap();
await Tests.fromId("search-input").element.typeText("Test");
await Tests.sleep(1000);
await Tests.fromText("1").isVisible();
await TestBuilder.create()
.prepare()
.createNote()
.waitAndTapById("search-header")
.typeTextById("search-input", "Test")
.wait(1000)
.isVisibleByText("1")
.run();
});
});

View File

@@ -18,74 +18,99 @@ 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) {
await Tests.fromId("icon-sort").waitAndTap();
await Tests.sleep(500);
await Tests.fromText(sorting).waitAndTap();
await device.pressBack();
}
import { TestBuilder } from "./utils";
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 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 Tests.sleep(500);
await device.pressBack();
await TestBuilder.create()
.prepare()
.createNote("Note 1", "Note 1")
.createNote("Note 2", "Note 2")
.waitAndTapByText("Note 1")
.addStep(async () => {
const webview = web();
await webview.element(by.web.className("ProseMirror")).tap();
await webview
.element(by.web.className("ProseMirror"))
.typeText("Edited ", true);
})
.pressBack()
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Date created")
.pressBack()
.waitAndTapById(notesnook.listitem.menu)
.pressBack()
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Date edited")
.pressBack()
.waitAndTapById(notesnook.listitem.menu)
.run();
});
it("Disable grouping", async () => {
await Tests.prepare();
await Tests.createNote("Note 1", "Note 1");
await sortBy("None");
await Tests.fromText("ALL").isVisible();
await TestBuilder.create()
.prepare()
.createNote("Note 1", "Note 1")
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("None")
.pressBack()
.isVisibleByText("ALL")
.run();
});
it("Group by Abc", async () => {
await Tests.prepare();
await Tests.createNote("Note 1", "Note 1");
await sortBy("Abc");
await Tests.fromText("N").isVisible();
await TestBuilder.create()
.prepare()
.createNote("Note 1", "Note 1")
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Abc")
.pressBack()
.isVisibleByText("N")
.run();
});
it("Group by Year", async () => {
await Tests.prepare();
await Tests.createNote("Note 1", "Note 1");
await sortBy("Year");
await TestBuilder.create()
.prepare()
.createNote("Note 1", "Note 1")
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Year")
.run();
});
it("Group by Week", async () => {
await Tests.prepare();
await Tests.createNote("Note 1", "Note 1");
await sortBy("Week");
await TestBuilder.create()
.prepare()
.createNote("Note 1", "Note 1")
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Week")
.run();
});
it("Group by Month", async () => {
await Tests.prepare();
await Tests.createNote("Note 1", "Note 1");
await sortBy("Month");
await TestBuilder.create()
.prepare()
.createNote("Note 1", "Note 1")
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Month")
.run();
});
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();
await TestBuilder.create()
.prepare()
.createNote("Note 1", "Note 1")
.waitAndTapById("icon-compact-mode")
.isNotVisibleByText("Note 1")
.waitAndTapById("icon-compact-mode")
.isVisibleByText("Note 1")
.run();
});
});

View File

@@ -18,95 +18,101 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { notesnook } from "../test.ids";
import { Tests } from "./utils";
import { TestBuilder } from "./utils";
describe("Tags", () => {
it("Create a tag", async () => {
await Tests.prepare();
await Tests.openSideMenu();
await Tests.fromId("tab-tags").waitAndTap();
await Tests.fromText("No tags").isVisible();
await Tests.fromId("sidebar-add-button").waitAndTap();
await Tests.fromId("input-value").element.typeText("testtag");
await Tests.fromText("Add").waitAndTap();
await Tests.fromText("testtag").isVisible();
await TestBuilder.create()
.prepare()
.openSideMenu()
.waitAndTapById("tab-tags")
.isVisibleByText("No tags")
.waitAndTapById("sidebar-add-button")
.typeTextById("input-value", "testtag")
.waitAndTapByText("Add")
.isVisibleByText("testtag")
.run();
});
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.openSideMenu();
await Tests.fromId("tab-tags").waitAndTap();
await Tests.fromText("#testtag").waitAndTap();
await Tests.fromText(note.body).isVisible();
await TestBuilder.create()
.prepare()
.createNote()
.saveResult()
.waitAndTapById(notesnook.listitem.menu)
.wait(500)
.waitAndTapByText("Add tag")
.typeTextById("tag-input", "testtag")
.waitAndTapByText('Add "#testtag"')
.isVisibleByText("#testtag")
.pressBack(2)
.openSideMenu()
.waitAndTapById("tab-tags")
.waitAndTapByText("#testtag")
.processResult(async (note) => {
await TestBuilder.create().isVisibleByText(note.body).run();
})
.run();
});
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();
await TestBuilder.create()
.prepare()
.createNote()
.waitAndTapById(notesnook.listitem.menu)
.wait(500)
.waitAndTapByText("Add tag")
.typeTextById("tag-input", "testtag")
.waitAndTapByText('Add "#testtag"')
.isVisibleByText("#testtag")
.waitAndTapByText("#testtag")
.pressBack(2)
.isNotVisibleByText("#testtag")
.run();
});
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.openSideMenu();
await Tests.fromId("tab-tags").waitAndTap();
await Tests.fromText("testtag").element.longPress();
await Tests.sleep(500);
await Tests.fromText("Add shortcut").waitAndTap();
await Tests.fromId("tab-home").waitAndTap();
await Tests.fromText("testtag").isVisible();
await TestBuilder.create()
.prepare()
.createNote()
.waitAndTapById(notesnook.listitem.menu)
.wait(500)
.waitAndTapByText("Add tag")
.typeTextById("tag-input", "testtag")
.waitAndTapByText('Add "#testtag"')
.isVisibleByText("#testtag")
.pressBack(2)
.openSideMenu()
.waitAndTapById("tab-tags")
.longPressByText("testtag")
.wait(500)
.waitAndTapByText("Add shortcut")
.waitAndTapById("tab-home")
.isVisibleByText("testtag")
.run();
});
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.openSideMenu();
await Tests.fromId("tab-tags").waitAndTap();
await Tests.fromText("testtag").element.longPress();
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();
await TestBuilder.create()
.prepare()
.createNote()
.waitAndTapById(notesnook.listitem.menu)
.wait(500)
.waitAndTapByText("Add tag")
.typeTextById("tag-input", "testtag")
.waitAndTapByText('Add "#testtag"')
.isVisibleByText("#testtag")
.pressBack(2)
.openSideMenu()
.waitAndTapById("tab-tags")
.longPressByText("testtag")
.wait(500)
.waitAndTapByText("Rename")
.wait(100)
.clearTextById("input-value")
.typeTextById("input-value", "testtag_edited")
.waitAndTapByText("Save")
.isVisibleByText("testtag_edited")
.run();
});
});

View File

@@ -171,7 +171,7 @@ class TestBuilder {
});
}
wait(duration: number) {
wait(duration = 500) {
return this.addStep(async () => {
await Tests.sleep(duration);
});
@@ -280,6 +280,13 @@ class TestBuilder {
});
}
tapReturnKeyById(id: string) {
return this.addStep(async () => {
const element = new Element("id", id);
await element.element.tapReturnKey();
});
}
tapByText(text: string, point?: Detox.Point2D) {
return this.addStep(async () => {
const element = new Element("text", text);
@@ -303,6 +310,12 @@ class TestBuilder {
});
}
clearTextById(id: string) {
return this.addStep(async () => {
await Element.fromId(id).element.clearText();
});
}
pressBack(count = 1) {
return this.addStep(async () => {
for (let i = 0; i < count; i++) {
@@ -311,6 +324,20 @@ class TestBuilder {
});
}
longPressByText(text: string) {
return this.addStep(async () => {
const element = new Element("text", text);
await element.element.longPress();
});
}
longPressById(id: string) {
return this.addStep(async () => {
const element = new Element("id", id);
await element.element.longPress();
});
}
async run() {
for (const step of this.steps) {
const result = step.call(this);

View File

@@ -18,134 +18,133 @@ 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";
import { TestBuilder, 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();
await TestBuilder.create()
.waitAndTapById(notesnook.listitem.menu)
.wait()
.waitAndTapById("icon-lock-unlock")
.wait()
.isVisibleByText("Lock")
.typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
.typeTextById(notesnook.ids.dialogs.vault.pwdAlt, "1234")
.waitAndTapByText("Lock")
.isVisibleById("note-locked-icon")
.run();
}
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();
await TestBuilder.create()
.waitAndTapById(notesnook.listitem.menu)
.wait()
.waitAndTapById("icon-lock-unlock")
.wait()
.typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
.waitAndTapByText("Unlock")
.isNotVisibleById("note-locked-icon")
.run();
}
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 openLockedNote(pwd = "1234") {
await TestBuilder.create()
.waitAndTapById(notesnook.ids.note.get(0))
.wait()
.addStep(async () => {
await web().element(by.web.name("password")).typeText(pwd, 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();
})
.run();
}
async function goToPrivacySecuritySettings() {
await Tests.openSideMenu();
await Tests.fromId("sidemenu-settings-icon").waitAndTap();
await Tests.sleep(300);
await Tests.fromText("Settings").waitAndTap();
await Tests.fromText("Vault").waitAndTap();
await TestBuilder.create()
.openSideMenu()
.waitAndTapById("sidemenu-settings-icon")
.wait()
.waitAndTapByText("Settings")
.waitAndTapByText("Vault")
.run();
}
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();
await TestBuilder.create()
.prepare()
.addStep(goToPrivacySecuritySettings)
.waitAndTapByText("Create vault")
.typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
.typeTextById(notesnook.ids.dialogs.vault.pwdAlt, "1234")
.waitAndTapByText("Create")
.isVisibleByText("Clear vault")
.run();
});
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 device.pressBack();
await Tests.sleep(500);
await openLockedNote("2362");
it.only("Change vault password", async () => {
await TestBuilder.create()
.prepare()
.createNote()
.addStep(lockNote)
.addStep(goToPrivacySecuritySettings)
.waitAndTapByText("Change vault password")
.typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
.typeTextById(notesnook.ids.dialogs.vault.changePwd, "2362")
.waitAndTapByText("Change")
.pressBack(3)
.addStep(async () => await openLockedNote("2362"))
.run();
});
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.sleep(300);
await Tests.fromText("Create vault").isVisible();
await device.pressBack();
await device.pressBack();
await device.pressBack();
await Tests.fromId(notesnook.listitem.menu).isVisible();
await TestBuilder.create()
.prepare()
.createNote()
.addStep(lockNote)
.addStep(goToPrivacySecuritySettings)
.waitAndTapByText("Delete vault")
.typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
.waitAndTapByText("Delete")
.isVisibleByText("Create vault")
.pressBack(3)
.isVisibleById(notesnook.listitem.menu)
.run();
});
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.sleep(300);
await Tests.fromText("Create vault").isVisible();
await device.pressBack();
await device.pressBack();
await device.pressBack();
await Tests.fromId(notesnook.listitem.menu).isNotVisible();
await TestBuilder.create()
.prepare()
.createNote()
.addStep(lockNote)
.addStep(goToPrivacySecuritySettings)
.waitAndTapByText("Delete vault")
.typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
.waitAndTapByText("Delete notes in this vault")
.waitAndTapByText("Delete")
.isVisibleByText("Create vault")
.pressBack(3)
.isNotVisibleById(notesnook.listitem.menu)
.run();
});
it("Add a note to vault", async () => {
await Tests.prepare();
await Tests.createNote();
await lockNote();
await openLockedNote();
await TestBuilder.create()
.prepare()
.createNote()
.addStep(lockNote)
.addStep(openLockedNote)
.run();
});
it("Remove note from vault", async () => {
await Tests.prepare();
await Tests.createNote();
await lockNote();
await removeFromVault();
await TestBuilder.create()
.prepare()
.createNote()
.addStep(lockNote)
.addStep(removeFromVault)
.run();
});
});

View File

@@ -87,6 +87,8 @@ export async function scheduleFullBackups() {
}
export async function shouldAddAutoBackupsDisabledNotice() {
if (isIgnored("autoBackupsOff")) return false;
const user = await db.user.getUser();
if (!user) return false;