import { Cookie } from "playwright"; import { expect } from "playwright/test"; import { App } from "../app"; type User = { email: string; password: string; }; type AuthCache = Array; const notion = { name: "Notion", userAuthEnvVars: { email: "ZYGON_GOOGLE_EMAIL", password: "ZYGON_GOOGLE_PASSWORD", }, login: async (user, page) => { await page.goto("https://www.notion.so/login"); const popupPromise = page.waitForEvent("popup"); await page.getByText("Continue with Google").click(); const popup = await popupPromise; await popup.locator("input#identifierId").fill(user.email); await popup.getByText("Next").click(); await popup.locator("input[type=password]").fill(user.password); await popup.getByText("Next").click(); await page.waitForSelector("[aria-label=Sidebar]"); }, cacheAuth: async (_, context) => { return await context.cookies(); }, restoreAuthCache: async (cache, _, context) => { await context.addCookies(cache); }, listCollaborators: async (page) => { await page.goto("https://www.notion.so"); await page.getByText("Settings").click(); await page.getByText("People", { exact: true }).click(); await page.getByText("Members", { exact: true }).click(); await expect(page.locator("[role=dialog] table tbody")).toBeVisible(); return await page.$$eval( "[role=dialog] table tbody tr td:first-of-type div:nth-child(2):has(> div)", (elements) => elements.map((element) => ({ fullName: element.querySelector("div:nth-child(1)")!.textContent!, email: element.querySelector("div:nth-child(2)")!.textContent!, })), ); }, addCollaborator: async (collaborator, page) => { await page.goto("https://www.notion.so"); await page.getByText("Settings").click(); await page.getByText("People", { exact: true }).click(); await page.getByText("Members", { exact: true }).click(); await page.getByRole("button", { name: "Add members" }).click(); await page.locator("input[type=email]").fill(collaborator.email); await page.getByText(collaborator.email).click(); await page.getByRole("button", { name: "Invite", exact: true }).click(); await expect(page.locator("[role=dialog]")).toHaveCount(1); }, removeCollaborator: async (collaborator, page) => { await page.goto("https://www.notion.so"); await page.getByText("Settings").click(); await page.getByText("People", { exact: true }).click(); await page.getByText("Members", { exact: true }).click(); await expect(page.locator("[role=dialog] table tbody")).toBeVisible(); const collaboratorList = await page.$$eval( "[role=dialog] table tbody tr td:first-of-type div:nth-child(2):has(> div)", (elements) => elements.map((element) => element.textContent), ); const collaboratorIndex = collaboratorList.findIndex((item) => item?.includes(collaborator.email), ); await page .locator( `[role=dialog] table tbody tr:nth-child(${collaboratorIndex + 1}) td:last-of-type [role=button]`, ) .click(); await page.getByText("Remove from workspace").click(); try { await page .getByRole("button", { name: "Continue", exact: true }) .click({ timeout: 300 }); } catch { // Sometimes Notion asks why we remove a user, sometimes it doesn't } await page.getByRole("button", { name: "Remove " }).click(); await expect(page.locator("[role=dialog]")).toHaveCount(1); }, } satisfies App; export default notion;