mobile: refactor e2e tests

Uses a builder pattern for writing tests to reduce code and simplify writing tests
This commit is contained in:
Ammar Ahmed
2025-10-06 12:11:02 +05:00
parent c77050eccc
commit 9aef8194f9
8 changed files with 505 additions and 482 deletions

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { authenticator } from "otplib"; import { authenticator } from "otplib";
import { Tests } from "./utils"; import { TestBuilder } from "./utils";
import dotenv from "dotenv"; import dotenv from "dotenv";
import path from "path"; 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() { // async function deleteAccount() {
// await tapByText("Account Settings"); // await tapByText("Account Settings");
// await sleep(2000); // await sleep(2000);
@@ -67,11 +53,27 @@ async function login() {
// await elementById("input.confirmPassword").tapReturnKey(); // 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", () => { describe("AUTH", () => {
it("Login", async () => { it("Login", async () => {
await Tests.prepare(); await TestBuilder.create()
await login(); .prepare()
await Tests.sleep(10000); .addStep(login)
await Tests.fromText("Login to encrypt and sync notes").isNotVisible(); .wait(3000)
.isNotVisibleByText("Notesnook Plans")
.run();
}); });
}); });

View File

@@ -1,3 +1,22 @@
/*
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 { notesnook } from "../test.ids";
import { TestBuilder } from "./utils"; import { TestBuilder } from "./utils";

View File

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

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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Tests } from "./utils"; import { TestBuilder } from "./utils";
describe("Search", () => { describe("Search", () => {
it("Search for a note", async () => { it("Search for a note", async () => {
await Tests.prepare(); await TestBuilder.create()
let note = await Tests.createNote(); .prepare()
await Tests.fromId("search-header").waitAndTap(); .createNote()
await Tests.fromId("search-input").element.typeText("Test"); .waitAndTapById("search-header")
await Tests.sleep(1000); .typeTextById("search-input", "Test")
await Tests.fromText("1").isVisible(); .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 { notesnook } from "../test.ids";
import { Tests } from "./utils"; import { TestBuilder } 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();
}
describe("Sort & filter", () => { describe("Sort & filter", () => {
it("Sort by date-edited/date-created", async () => { it("Sort by date-edited/date-created", async () => {
await Tests.prepare(); await TestBuilder.create()
let webview = web(); .prepare()
await Tests.createNote("Note 1", "Note 1"); .createNote("Note 1", "Note 1")
await Tests.createNote("Note 2", "Note 2"); .createNote("Note 2", "Note 2")
await Tests.fromText("Note 1").waitAndTap(); .waitAndTapByText("Note 1")
await webview.element(by.web.className("ProseMirror")).tap(); .addStep(async () => {
await webview const webview = web();
.element(by.web.className("ProseMirror")) await webview.element(by.web.className("ProseMirror")).tap();
.typeText("Edited ", true); await webview
await device.pressBack(); .element(by.web.className("ProseMirror"))
await sortBy("Date created"); .typeText("Edited ", true);
await Tests.fromId(notesnook.listitem.menu).waitAndTap(); })
await device.pressBack(); .pressBack()
await sortBy("Date edited"); .waitAndTapById("icon-sort")
await Tests.fromId(notesnook.listitem.menu).waitAndTap(); .wait(500)
await Tests.sleep(500); .waitAndTapByText("Date created")
await device.pressBack(); .pressBack()
.waitAndTapById(notesnook.listitem.menu)
.pressBack()
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Date edited")
.pressBack()
.waitAndTapById(notesnook.listitem.menu)
.run();
}); });
it("Disable grouping", async () => { it("Disable grouping", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote("Note 1", "Note 1"); .prepare()
await sortBy("None"); .createNote("Note 1", "Note 1")
await Tests.fromText("ALL").isVisible(); .waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("None")
.pressBack()
.isVisibleByText("ALL")
.run();
}); });
it("Group by Abc", async () => { it("Group by Abc", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote("Note 1", "Note 1"); .prepare()
await sortBy("Abc"); .createNote("Note 1", "Note 1")
await Tests.fromText("N").isVisible(); .waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Abc")
.pressBack()
.isVisibleByText("N")
.run();
}); });
it("Group by Year", async () => { it("Group by Year", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote("Note 1", "Note 1"); .prepare()
await sortBy("Year"); .createNote("Note 1", "Note 1")
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Year")
.run();
}); });
it("Group by Week", async () => { it("Group by Week", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote("Note 1", "Note 1"); .prepare()
await sortBy("Week"); .createNote("Note 1", "Note 1")
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Week")
.run();
}); });
it("Group by Month", async () => { it("Group by Month", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote("Note 1", "Note 1"); .prepare()
await sortBy("Month"); .createNote("Note 1", "Note 1")
.waitAndTapById("icon-sort")
.wait(500)
.waitAndTapByText("Month")
.run();
}); });
it("Compact mode", async () => { it("Compact mode", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote("Note 1", "Note 1"); .prepare()
await Tests.fromId("icon-compact-mode").waitAndTap(); .createNote("Note 1", "Note 1")
await Tests.fromText("Note 1").isNotVisible(); .waitAndTapById("icon-compact-mode")
await Tests.fromId("icon-compact-mode").waitAndTap(); .isNotVisibleByText("Note 1")
await Tests.fromText("Note 1").isVisible(); .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 { notesnook } from "../test.ids";
import { Tests } from "./utils"; import { TestBuilder } from "./utils";
describe("Tags", () => { describe("Tags", () => {
it("Create a tag", async () => { it("Create a tag", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.openSideMenu(); .prepare()
await Tests.fromId("tab-tags").waitAndTap(); .openSideMenu()
.waitAndTapById("tab-tags")
await Tests.fromText("No tags").isVisible(); .isVisibleByText("No tags")
await Tests.fromId("sidebar-add-button").waitAndTap(); .waitAndTapById("sidebar-add-button")
.typeTextById("input-value", "testtag")
await Tests.fromId("input-value").element.typeText("testtag"); .waitAndTapByText("Add")
.isVisibleByText("testtag")
await Tests.fromText("Add").waitAndTap(); .run();
await Tests.fromText("testtag").isVisible();
}); });
it("Tag a note", async () => { it("Tag a note", async () => {
await Tests.prepare(); await TestBuilder.create()
let note = await Tests.createNote(); .prepare()
await Tests.fromId(notesnook.listitem.menu).waitAndTap(); .createNote()
await Tests.sleep(500); .saveResult()
await Tests.fromText("Add tag").waitAndTap(); .waitAndTapById(notesnook.listitem.menu)
await Tests.fromId("tag-input").element.typeText("testtag"); .wait(500)
await Tests.fromText('Add "#testtag"').waitAndTap(); .waitAndTapByText("Add tag")
await Tests.fromText("#testtag").isVisible(); .typeTextById("tag-input", "testtag")
await device.pressBack(); .waitAndTapByText('Add "#testtag"')
await device.pressBack(); .isVisibleByText("#testtag")
await Tests.openSideMenu(); .pressBack(2)
await Tests.fromId("tab-tags").waitAndTap(); .openSideMenu()
await Tests.fromText("#testtag").waitAndTap(); .waitAndTapById("tab-tags")
await Tests.fromText(note.body).isVisible(); .waitAndTapByText("#testtag")
.processResult(async (note) => {
await TestBuilder.create().isVisibleByText(note.body).run();
})
.run();
}); });
it("Untag a note", async () => { it("Untag a note", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote(); .prepare()
await Tests.fromId(notesnook.listitem.menu).waitAndTap(); .createNote()
await Tests.sleep(500); .waitAndTapById(notesnook.listitem.menu)
await Tests.fromText("Add tag").waitAndTap(); .wait(500)
await Tests.fromId("tag-input").element.typeText("testtag"); .waitAndTapByText("Add tag")
await Tests.fromText('Add "#testtag"').waitAndTap(); .typeTextById("tag-input", "testtag")
await Tests.fromText("#testtag").isVisible(); .waitAndTapByText('Add "#testtag"')
await Tests.fromText("#testtag").waitAndTap(); .isVisibleByText("#testtag")
await device.pressBack(); .waitAndTapByText("#testtag")
await device.pressBack(); .pressBack(2)
await Tests.fromText("#testtag").isNotVisible(); .isNotVisibleByText("#testtag")
.run();
}); });
it("Create shortcut of a tag", async () => { it("Create shortcut of a tag", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote(); .prepare()
await Tests.fromId(notesnook.listitem.menu).waitAndTap(); .createNote()
await Tests.sleep(500); .waitAndTapById(notesnook.listitem.menu)
await Tests.fromText("Add tag").waitAndTap(); .wait(500)
await Tests.fromId("tag-input").element.typeText("testtag"); .waitAndTapByText("Add tag")
await Tests.fromText('Add "#testtag"').waitAndTap(); .typeTextById("tag-input", "testtag")
await Tests.fromText("#testtag").isVisible(); .waitAndTapByText('Add "#testtag"')
await device.pressBack(); .isVisibleByText("#testtag")
await device.pressBack(); .pressBack(2)
await Tests.openSideMenu(); .openSideMenu()
await Tests.fromId("tab-tags").waitAndTap(); .waitAndTapById("tab-tags")
await Tests.fromText("testtag").element.longPress(); .longPressByText("testtag")
await Tests.sleep(500); .wait(500)
await Tests.fromText("Add shortcut").waitAndTap(); .waitAndTapByText("Add shortcut")
await Tests.fromId("tab-home").waitAndTap(); .waitAndTapById("tab-home")
await Tests.fromText("testtag").isVisible(); .isVisibleByText("testtag")
.run();
}); });
it("Rename a tag", async () => { it("Rename a tag", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote(); .prepare()
await Tests.fromId(notesnook.listitem.menu).waitAndTap(); .createNote()
await Tests.sleep(500); .waitAndTapById(notesnook.listitem.menu)
await Tests.fromText("Add tag").waitAndTap(); .wait(500)
await Tests.fromId("tag-input").element.typeText("testtag"); .waitAndTapByText("Add tag")
await Tests.fromText('Add "#testtag"').waitAndTap(); .typeTextById("tag-input", "testtag")
await Tests.fromText("#testtag").isVisible(); .waitAndTapByText('Add "#testtag"')
await device.pressBack(); .isVisibleByText("#testtag")
await device.pressBack(); .pressBack(2)
await Tests.openSideMenu(); .openSideMenu()
await Tests.fromId("tab-tags").waitAndTap(); .waitAndTapById("tab-tags")
await Tests.fromText("testtag").element.longPress(); .longPressByText("testtag")
await Tests.sleep(500); .wait(500)
await Tests.fromText("Rename").waitAndTap(); .waitAndTapByText("Rename")
await Tests.sleep(100); .wait(100)
await Tests.fromId("input-value").element.clearText(); .clearTextById("input-value")
await Tests.fromId("input-value").element.typeText("testtag_edited"); .typeTextById("input-value", "testtag_edited")
await Tests.fromText("Save").waitAndTap(); .waitAndTapByText("Save")
await Tests.fromText("testtag_edited").isVisible(); .isVisibleByText("testtag_edited")
.run();
}); });
}); });

View File

@@ -171,7 +171,7 @@ class TestBuilder {
}); });
} }
wait(duration: number) { wait(duration = 500) {
return this.addStep(async () => { return this.addStep(async () => {
await Tests.sleep(duration); 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) { tapByText(text: string, point?: Detox.Point2D) {
return this.addStep(async () => { return this.addStep(async () => {
const element = new Element("text", text); 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) { pressBack(count = 1) {
return this.addStep(async () => { return this.addStep(async () => {
for (let i = 0; i < count; i++) { 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() { async run() {
for (const step of this.steps) { for (const step of this.steps) {
const result = step.call(this); 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 { expect } from "detox";
import { notesnook } from "../test.ids"; import { notesnook } from "../test.ids";
import { Tests } from "./utils"; import { TestBuilder, Tests } from "./utils";
async function lockNote() { async function lockNote() {
await Tests.fromId(notesnook.listitem.menu).waitAndTap(); await TestBuilder.create()
await Tests.sleep(500); .waitAndTapById(notesnook.listitem.menu)
await Tests.fromId("icon-lock-unlock").waitAndTap(); .wait()
await Tests.sleep(500); .waitAndTapById("icon-lock-unlock")
await Tests.fromText("Lock").isVisible(); .wait()
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText("1234"); .isVisibleByText("Lock")
await Tests.fromId(notesnook.ids.dialogs.vault.pwdAlt).element.typeText( .typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
"1234" .typeTextById(notesnook.ids.dialogs.vault.pwdAlt, "1234")
); .waitAndTapByText("Lock")
await Tests.fromText("Lock").waitAndTap(); .isVisibleById("note-locked-icon")
await Tests.fromId("note-locked-icon").isVisible(); .run();
} }
async function removeFromVault() { async function removeFromVault() {
await Tests.fromId(notesnook.listitem.menu).waitAndTap(); await TestBuilder.create()
await Tests.sleep(500); .waitAndTapById(notesnook.listitem.menu)
await Tests.fromId("icon-lock-unlock").waitAndTap(); .wait()
await Tests.sleep(500); .waitAndTapById("icon-lock-unlock")
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText("1234"); .wait()
await Tests.fromText("Unlock").waitAndTap(); .typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
await Tests.fromId("note-locked-icon").isNotVisible(); .waitAndTapByText("Unlock")
.isNotVisibleById("note-locked-icon")
.run();
} }
async function openLockedNote(pwd?: string) { async function openLockedNote(pwd = "1234") {
await Tests.fromId(notesnook.ids.note.get(0)).waitAndTap(); await TestBuilder.create()
await Tests.sleep(500); .waitAndTapById(notesnook.ids.note.get(0))
await web() .wait()
.element(by.web.name("password")) .addStep(async () => {
.typeText(pwd || "1234", false); await web().element(by.web.name("password")).typeText(pwd, false);
await web().element(by.web.className("unlock-note")).tap(); await web().element(by.web.className("unlock-note")).tap();
await Tests.sleep(500); await Tests.sleep(500);
await expect(web().element(by.web.className("unlock-note"))).not.toExist(); await expect(
web().element(by.web.className("unlock-note"))
).not.toExist();
})
.run();
} }
async function goToPrivacySecuritySettings() { async function goToPrivacySecuritySettings() {
await Tests.openSideMenu(); await TestBuilder.create()
await Tests.fromId("sidemenu-settings-icon").waitAndTap(); .openSideMenu()
await Tests.sleep(300); .waitAndTapById("sidemenu-settings-icon")
await Tests.fromText("Settings").waitAndTap(); .wait()
await Tests.fromText("Vault").waitAndTap(); .waitAndTapByText("Settings")
.waitAndTapByText("Vault")
.run();
} }
describe("VAULT", () => { describe("VAULT", () => {
it("Create vault from settings", async () => { it("Create vault from settings", async () => {
await Tests.prepare(); await TestBuilder.create()
await goToPrivacySecuritySettings(); .prepare()
await Tests.fromText("Create vault").waitAndTap(); .addStep(goToPrivacySecuritySettings)
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText( .waitAndTapByText("Create vault")
"1234" .typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
); .typeTextById(notesnook.ids.dialogs.vault.pwdAlt, "1234")
await Tests.fromId(notesnook.ids.dialogs.vault.pwdAlt).element.typeText( .waitAndTapByText("Create")
"1234" .isVisibleByText("Clear vault")
); .run();
await Tests.fromText("Create").waitAndTap();
await Tests.fromText("Clear vault").isVisible();
}); });
it("Change vault password", async () => { it.only("Change vault password", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote(); .prepare()
await lockNote(); .createNote()
await goToPrivacySecuritySettings(); .addStep(lockNote)
await Tests.fromText("Change vault password").waitAndTap(); .addStep(goToPrivacySecuritySettings)
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText( .waitAndTapByText("Change vault password")
"1234" .typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
); .typeTextById(notesnook.ids.dialogs.vault.changePwd, "2362")
await Tests.fromId(notesnook.ids.dialogs.vault.changePwd).element.typeText( .waitAndTapByText("Change")
"2362" .pressBack(3)
); .addStep(async () => await openLockedNote("2362"))
await Tests.fromText("Change").waitAndTap(); .run();
await device.pressBack();
await device.pressBack();
await device.pressBack();
await Tests.sleep(500);
await openLockedNote("2362");
}); });
it("Delete vault", async () => { it("Delete vault", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote(); .prepare()
await lockNote(); .createNote()
await goToPrivacySecuritySettings(); .addStep(lockNote)
await Tests.fromText("Delete vault").waitAndTap(); .addStep(goToPrivacySecuritySettings)
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText( .waitAndTapByText("Delete vault")
"1234" .typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
); .waitAndTapByText("Delete")
await Tests.fromText("Delete").waitAndTap(); .isVisibleByText("Create vault")
await Tests.sleep(300); .pressBack(3)
await Tests.fromText("Create vault").isVisible(); .isVisibleById(notesnook.listitem.menu)
await device.pressBack(); .run();
await device.pressBack();
await device.pressBack();
await Tests.fromId(notesnook.listitem.menu).isVisible();
}); });
it("Delete vault with locked notes", async () => { it("Delete vault with locked notes", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote(); .prepare()
await lockNote(); .createNote()
await goToPrivacySecuritySettings(); .addStep(lockNote)
await Tests.fromText("Delete vault").waitAndTap(); .addStep(goToPrivacySecuritySettings)
await Tests.fromId(notesnook.ids.dialogs.vault.pwd).element.typeText( .waitAndTapByText("Delete vault")
"1234" .typeTextById(notesnook.ids.dialogs.vault.pwd, "1234")
); .waitAndTapByText("Delete notes in this vault")
await Tests.fromText("Delete notes in this vault").waitAndTap(); .waitAndTapByText("Delete")
await Tests.fromText("Delete").waitAndTap(); .isVisibleByText("Create vault")
await Tests.sleep(300); .pressBack(3)
await Tests.fromText("Create vault").isVisible(); .isNotVisibleById(notesnook.listitem.menu)
await device.pressBack(); .run();
await device.pressBack();
await device.pressBack();
await Tests.fromId(notesnook.listitem.menu).isNotVisible();
}); });
it("Add a note to vault", async () => { it("Add a note to vault", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote(); .prepare()
await lockNote(); .createNote()
await openLockedNote(); .addStep(lockNote)
.addStep(openLockedNote)
.run();
}); });
it("Remove note from vault", async () => { it("Remove note from vault", async () => {
await Tests.prepare(); await TestBuilder.create()
await Tests.createNote(); .prepare()
await lockNote(); .createNote()
await removeFromVault(); .addStep(lockNote)
.addStep(removeFromVault)
.run();
}); });
}); });