web: add tests for backups (#1542)

Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
This commit is contained in:
Muhammad Ali
2023-01-04 12:34:15 +05:00
committed by GitHub
parent d4a3b53c1b
commit 2beccd6918
7 changed files with 127 additions and 4 deletions

View File

@@ -0,0 +1,74 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 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 { test, Browser, expect } from "@playwright/test";
import { AppModel } from "./models/app.model";
import { NOTE, USER } from "./utils";
test("create a backup", async ({ page }) => {
const app = new AppModel(page);
await app.goto();
const notes = await app.goToNotes();
await notes.createNote(NOTE);
const settings = await app.goToSettings();
const backup = await settings.createBackup();
expect(backup.length > 0).toBeTruthy();
});
test.setTimeout(45 * 1000);
test("restore a backup", async ({ page }) => {
const app = new AppModel(page);
await app.goto();
const settings = await app.goToSettings();
await settings.restoreData("backup.nnbackup", USER.CURRENT.password);
const notes = await app.goToNotes();
expect(await notes.isEmpty()).toBeTruthy();
const notebooks = await app.goToNotebooks();
expect(await notebooks.isEmpty()).toBeTruthy();
const favotites = await app.goToFavorites();
expect(await favotites.isEmpty()).toBeTruthy();
const tags = await app.goToTags();
expect(await tags.isEmpty()).toBeTruthy();
});
test("create an encrypted backup", async ({ page }) => {
const app = new AppModel(page);
await app.auth.goto();
await app.auth.login(USER.CURRENT);
const settings = await app.goToSettings();
const backup = await settings.createBackup(USER.CURRENT.password);
expect(backup.length > 0).toBeTruthy();
});
test("restore an encrypted backup", async ({ page }) => {
const app = new AppModel(page);
await app.goto();
const settings = await app.goToSettings();
await settings.restoreData("encrypted.nnbackup", USER.CURRENT.password);
const notes = await app.goToNotes();
expect(await notes.isEmpty()).toBeTruthy();
const notebooks = await app.goToNotebooks();
expect(await notebooks.isEmpty()).toBeTruthy();
const favotites = await app.goToFavorites();
expect(await favotites.isEmpty()).toBeTruthy();
const tags = await app.goToTags();
expect(await tags.isEmpty()).toBeTruthy();
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Locator, Page } from "@playwright/test";
import { getTestId } from "../utils";
import { downloadAndReadFile, getTestId, uploadFile } from "../utils";
import { confirmDialog, fillPasswordDialog, waitToHaveText } from "./utils";
export class SettingsViewModel {
@@ -26,6 +26,10 @@ export class SettingsViewModel {
private readonly logoutButton: Locator;
private readonly accountStatusContainer: Locator;
private readonly backupRecoveryKeyButton: Locator;
private readonly backupRestoreContainer: Locator;
private readonly backupData: Locator;
private readonly restoreBackup: Locator;
private readonly encyptBackups: Locator;
constructor(page: Page) {
this.page = page;
this.logoutButton = page.locator(getTestId("settings-logout"));
@@ -33,6 +37,10 @@ export class SettingsViewModel {
this.backupRecoveryKeyButton = page.locator(
getTestId("backup-recovery-key")
);
this.backupRestoreContainer = page.locator(getTestId("backup-restore"));
this.backupData = page.locator(getTestId("backup-data"));
this.restoreBackup = page.locator(getTestId("restore-backup"));
this.encyptBackups = page.locator(getTestId("encrypt-backups"));
}
async logout() {
@@ -59,4 +67,19 @@ export class SettingsViewModel {
async isLoggedIn() {
return await this.accountStatusContainer.isVisible();
}
async createBackup(password?: string) {
await this.backupRestoreContainer.click();
if (password) await this.encyptBackups.click();
await this.backupData.click();
if (password) await fillPasswordDialog(this.page, password);
return await downloadAndReadFile(this.page, this.backupData, "utf-8");
}
async restoreData(filename: string, password: string | undefined) {
await this.backupRestoreContainer.click();
await this.restoreBackup.click();
await uploadFile(this.page, this.restoreBackup, filename);
if (password) await fillPasswordDialog(this.page, password);
}
}

View File

@@ -105,6 +105,15 @@ async function downloadAndReadFile(
return fs.readFileSync(path, { encoding });
}
async function uploadFile(page: Page, action: Locator, filename: string) {
const [fileChooser] = await Promise.all([
page.waitForEvent("filechooser"),
await action.click()
]);
await fileChooser.setFiles(path.join(__dirname, "../data", filename));
}
function isTestAll() {
return process.env.TEST_ALL === "true";
}
@@ -135,6 +144,7 @@ export {
createNote,
editNote,
downloadAndReadFile,
uploadFile,
isTestAll,
orderByOptions,
sortByOptions,

View File

@@ -25,7 +25,16 @@ import { Flex } from "@theme-ui/components";
import Switch from "../switch";
function Toggle(props) {
const { title, onTip, offTip, isToggled, onToggled, onlyIf, premium } = props;
const {
title,
onTip,
offTip,
isToggled,
onToggled,
onlyIf,
premium,
testId
} = props;
const onClick = useCallback(async () => {
if (isUserPremium() || !premium || isToggled) onToggled();
else {
@@ -37,6 +46,7 @@ function Toggle(props) {
return (
<Flex
onClick={onClick}
data-test-id={testId}
py={2}
sx={{
cursor: "pointer",

View File

@@ -54,7 +54,7 @@ import { appVersion } from "../utils/version";
import { CHECK_IDS } from "@notesnook/core/common";
import Tip from "../components/tip";
import Toggle from "../components/toggle";
import { isDesktop, isMacStoreApp } from "../utils/platform";
import { isDesktop, isMacStoreApp, isTesting } from "../utils/platform";
import Vault from "../common/vault";
import { isUserPremium } from "../hooks/use-is-user-premium";
import { Slider } from "@theme-ui/components";
@@ -529,6 +529,7 @@ function Settings() {
</>
)}
<Header
testId={"backup-restore"}
title="Backup & restore"
isOpen={groups.backup}
onClick={() => {
@@ -539,6 +540,7 @@ function Settings() {
{groups.backup && (
<>
<Button
data-test-id={"backup-data"}
variant="list"
onClick={async () => {
if (!isUserPremium() && encryptBackups) toggleEncryptBackups();
@@ -571,9 +573,10 @@ function Settings() {
);
}}
/>
{isLoggedIn && (
{(isLoggedIn || isTesting()) && (
<>
<Button
data-test-id="restore-backup"
variant="list"
onClick={async () => {
await importBackup();
@@ -587,6 +590,7 @@ function Settings() {
</Button>
<Toggle
title="Encrypt backups"
testId="encrypt-backups"
onTip="All backup files will be encrypted"
offTip="Backup files will not be encrypted"
onToggled={toggleEncryptBackups}