Notes/e2e/support/app.ts

129 lines
4.2 KiB
TypeScript
Raw Normal View History

import { expect, Locator, Page } from "@playwright/test";
import type { BrowserContext } from "@playwright/test";
interface GotoOpts {
2025-01-17 23:13:55 +02:00
url?: string;
isMobile?: boolean;
}
2025-01-11 00:13:46 +02:00
2025-01-13 17:42:21 +02:00
const BASE_URL = "http://127.0.0.1:8082";
2025-01-11 00:13:46 +02:00
export default class App {
readonly page: Page;
readonly context: BrowserContext;
2025-01-11 00:13:46 +02:00
readonly tabBar: Locator;
readonly noteTree: Locator;
readonly noteTreeHoistedNote: Locator;
readonly launcherBar: Locator;
2025-01-11 12:48:59 +02:00
readonly currentNoteSplit: Locator;
readonly currentNoteSplitTitle: Locator;
readonly currentNoteSplitContent: Locator;
readonly sidebar: Locator;
2025-01-11 00:13:46 +02:00
constructor(page: Page, context: BrowserContext) {
2025-01-11 00:13:46 +02:00
this.page = page;
this.context = context;
2025-01-11 00:13:46 +02:00
this.tabBar = page.locator(".tab-row-widget-container");
this.noteTree = page.locator(".tree-wrapper");
this.noteTreeHoistedNote = this.noteTree.locator(".fancytree-node", { has: page.locator(".unhoist-button") });
this.launcherBar = page.locator("#launcher-container");
2025-03-02 20:47:57 +01:00
this.currentNoteSplit = page.locator(".note-split:not(.hidden-ext)");
this.currentNoteSplitTitle = this.currentNoteSplit.locator(".note-title");
this.currentNoteSplitContent = this.currentNoteSplit.locator(".note-detail-printable.visible");
this.sidebar = page.locator("#right-pane");
2025-01-11 00:13:46 +02:00
}
2025-01-17 23:13:55 +02:00
async goto({ url, isMobile }: GotoOpts = {}) {
await this.context.addCookies([
{
2025-01-13 17:42:21 +02:00
url: BASE_URL,
name: "trilium-device",
2025-01-17 23:13:55 +02:00
value: isMobile ? "mobile" : "desktop"
}
]);
2025-01-17 23:13:55 +02:00
if (!url) {
url = "/";
}
await this.page.goto(url, { waitUntil: "networkidle", timeout: 30_000 });
2025-01-11 00:13:46 +02:00
// Wait for the page to load.
2025-01-17 23:13:55 +02:00
if (url === "/") {
2025-03-02 20:47:57 +01:00
await expect(this.page.locator(".tree")).toContainText("Trilium Integration Test");
2025-01-17 23:13:55 +02:00
await this.closeAllTabs();
}
2025-01-11 00:13:46 +02:00
}
2025-01-11 12:48:59 +02:00
async goToNoteInNewTab(noteTitle: string) {
const autocomplete = this.currentNoteSplit.locator(".note-autocomplete");
await autocomplete.fill(noteTitle);
await expect(this.currentNoteSplit.locator(".note-detail-empty-results")).toContainText(noteTitle);
2025-01-11 12:48:59 +02:00
await autocomplete.press("ArrowDown");
await autocomplete.press("Enter");
}
async goToSettings() {
await this.page.locator(".launcher-button.bx-cog").click();
}
2025-01-11 00:13:46 +02:00
getTab(tabIndex: number) {
return this.tabBar.locator(".note-tab-wrapper").nth(tabIndex);
}
getActiveTab() {
return this.tabBar.locator(".note-tab[active]");
}
/**
* Closes all the tabs in the client by issuing a command.
*/
2025-01-11 00:13:46 +02:00
async closeAllTabs() {
await this.triggerCommand("closeAllTabs");
2025-03-18 22:01:08 +01:00
// Page in Playwright is not updated somehow, need to click on the tab to make sure it's rendered
await this.getTab(0).click();
2025-01-11 00:13:46 +02:00
}
/**
* Adds a new tab by cliking on the + button near the tab bar.
*/
2025-01-11 00:13:46 +02:00
async addNewTab() {
await this.page.locator('[data-trigger-command="openNewTab"]').click();
}
/**
* Looks for a given title in the note tree and clicks on it. Useful for selecting option pages in settings in a similar fashion as the user.
* @param title the title of the note to click, as displayed in the note tree.
*/
2025-01-11 00:13:46 +02:00
async clickNoteOnNoteTreeByTitle(title: string) {
await this.noteTree.getByText(title).click();
}
/**
* Executes any Trilium command on the client.
* @param command the command to send.
*/
async triggerCommand(command: string) {
await this.page.evaluate(async (command: string) => {
await (window as any).glob.appContext.triggerCommand(command);
}, command);
2025-01-11 00:13:46 +02:00
}
2025-01-13 17:42:21 +02:00
async setOption(key: string, value: string) {
const csrfToken = await this.page.evaluate(() => {
return (window as any).glob.csrfToken;
});
expect(csrfToken).toBeTruthy();
2025-03-02 20:47:57 +01:00
await expect(
await this.page.request.put(`${BASE_URL}/api/options/${key}/${value}`, {
headers: {
"x-csrf-token": csrfToken
}
})
).toBeOK();
2025-01-13 17:42:21 +02:00
}
2025-01-11 00:13:46 +02:00
}