| 
									
										
										
										
											2025-01-12 18:05:24 +02:00
										 |  |  | 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; | 
					
						
							| 
									
										
										
										
											2025-01-12 18:05:24 +02:00
										 |  |  |     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; | 
					
						
							| 
									
										
										
										
											2025-01-12 18:05:24 +02:00
										 |  |  |     readonly context: BrowserContext; | 
					
						
							| 
									
										
										
										
											2025-01-11 00:13:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     readonly tabBar: Locator; | 
					
						
							|  |  |  |     readonly noteTree: Locator; | 
					
						
							| 
									
										
										
										
											2025-01-17 20:15:48 +02:00
										 |  |  |     readonly launcherBar: Locator; | 
					
						
							| 
									
										
										
										
											2025-01-11 12:48:59 +02:00
										 |  |  |     readonly currentNoteSplit: Locator; | 
					
						
							| 
									
										
										
										
											2025-01-11 13:36:56 +02:00
										 |  |  |     readonly sidebar: Locator; | 
					
						
							| 
									
										
										
										
											2025-01-11 00:13:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-12 18:05:24 +02:00
										 |  |  |     constructor(page: Page, context: BrowserContext) { | 
					
						
							| 
									
										
										
										
											2025-01-11 00:13:46 +02:00
										 |  |  |         this.page = page; | 
					
						
							| 
									
										
										
										
											2025-01-12 18:05:24 +02:00
										 |  |  |         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"); | 
					
						
							| 
									
										
										
										
											2025-01-17 20:15:48 +02:00
										 |  |  |         this.launcherBar = page.locator("#launcher-container"); | 
					
						
							| 
									
										
										
										
											2025-01-11 12:48:59 +02:00
										 |  |  |         this.currentNoteSplit = page.locator(".note-split:not(.hidden-ext)") | 
					
						
							| 
									
										
										
										
											2025-01-11 13:36:56 +02:00
										 |  |  |         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 = {}) { | 
					
						
							| 
									
										
										
										
											2025-01-12 18:05:24 +02:00
										 |  |  |         await this.context.addCookies([ | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-01-13 17:42:21 +02:00
										 |  |  |                 url: BASE_URL, | 
					
						
							| 
									
										
										
										
											2025-01-12 18:05:24 +02:00
										 |  |  |                 name: "trilium-device", | 
					
						
							| 
									
										
										
										
											2025-01-17 23:13:55 +02:00
										 |  |  |                 value: isMobile ? "mobile" : "desktop" | 
					
						
							| 
									
										
										
										
											2025-01-12 18:05:24 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-17 23:13:55 +02:00
										 |  |  |         if (!url) { | 
					
						
							|  |  |  |             url = "/"; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         await this.page.goto(url, { waitUntil: "networkidle" }); | 
					
						
							| 
									
										
										
										
											2025-01-11 00:13:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Wait for the page to load.
 | 
					
						
							| 
									
										
										
										
											2025-01-17 23:13:55 +02:00
										 |  |  |         if (url === "/") { | 
					
						
							|  |  |  |             await expect(this.page.locator(".tree")) | 
					
						
							|  |  |  |                 .toContainText("Trilium Integration Test"); | 
					
						
							|  |  |  |             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 autocomplete.press("ArrowDown"); | 
					
						
							|  |  |  |         await autocomplete.press("Enter"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-12 17:28:41 +02:00
										 |  |  |     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]"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 17:21:50 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Closes all the tabs in the client by issuing a command. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2025-01-11 00:13:46 +02:00
										 |  |  |     async closeAllTabs() { | 
					
						
							| 
									
										
										
										
											2025-01-13 17:21:50 +02:00
										 |  |  |         await this.triggerCommand("closeAllTabs"); | 
					
						
							| 
									
										
										
										
											2025-01-11 00:13:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 17:21:50 +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(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 17:21:50 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * 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) { | 
					
						
							| 
									
										
										
										
											2025-01-13 17:21:50 +02:00
										 |  |  |         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(); | 
					
						
							|  |  |  |         await expect(await this.page.request.put(`${BASE_URL}/api/options/${key}/${value}`, { | 
					
						
							|  |  |  |             headers: { | 
					
						
							|  |  |  |                 "x-csrf-token": csrfToken | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         })).toBeOK(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 00:13:46 +02:00
										 |  |  | } |