Skip to content

Commit d71de46

Browse files
committed
Also grant access
1 parent b2461e2 commit d71de46

1 file changed

Lines changed: 28 additions & 6 deletions

File tree

src/services/notion.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,15 @@ class NotionServiceSession extends BrowserFollowupServiceSession {
3636

3737
await page.goto(NOTION_INTEGRATIONS_URL);
3838

39+
// Annoyingly, Notion's DOM is devoid of IDs,
40+
// so we have to use broad locators with nth.
41+
3942
// Integration name
4043
await page.getByRole('textbox').click();
4144
await page.getByRole('textbox').fill(generateLatchkeyAppName());
42-
// Workspace
45+
// Workspace - initially empty
4346
await page.getByRole('button').filter({ hasText: /^$/ }).click();
47+
// Just pick the first workspace
4448
await page.getByRole('menuitem').click();
4549
// Create integration
4650
await page.getByRole('button').last().click();
@@ -50,22 +54,40 @@ class NotionServiceSession extends BrowserFollowupServiceSession {
5054
.getByRole('button')
5155
.nth(0)
5256
.click({ timeout: DEFAULT_TIMEOUT_MS });
57+
// Token input
58+
const tokenTextbox = page.locator('input[type="password"]');
59+
// We have to save the element handle because the same element's type changes to text after clicking "Show".
60+
const tokenTextboxElement = (await tokenTextbox.elementHandle())!;
5361
// Show
54-
await page
55-
.locator('input[type="password"]')
62+
await tokenTextbox
5663
.locator('..')
5764
.getByRole('button')
5865
.nth(1)
5966
.click({ timeout: DEFAULT_TIMEOUT_MS });
6067

61-
const tokenTextbox = page.locator('input[type="password"]');
62-
await tokenTextbox.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
68+
let token = '';
69+
// Poll for up to 2 seconds for the token to be revealed
70+
for (let i = 0; i < 20; i++) {
71+
token = (await tokenTextboxElement.inputValue()).trim();
72+
if (token !== '') {
73+
break;
74+
}
75+
await page.waitForTimeout(100);
76+
}
6377

64-
const token = await tokenTextbox.inputValue();
6578
if (token === '') {
6679
throw new LoginFailedError('Failed to extract token from Notion.');
6780
}
6881

82+
// Grant access.
83+
// This part of the flow is too annoying to automate without using the labels...
84+
await page.getByRole('tab', { name: 'Access' }).click();
85+
await page.getByRole('button', { name: 'Edit access' }).click();
86+
await page.getByRole('button', { name: 'Private' }).click();
87+
await page.getByRole('button', { name: 'Select all' }).click();
88+
await page.getByRole('button', { name: 'Save' }).click();
89+
await page.getByRole('dialog').waitFor({ state: 'hidden' });
90+
6991
await page.close();
7092

7193
return new AuthorizationBearer(token);

0 commit comments

Comments
 (0)