Skip to content

Commit 42a4388

Browse files
Group e2e tests (tldraw#7129)
Add some basic group e2e tests. There's a ton more we could add, but went for the most basic ones for now as they do tend to be on the slow side. ### Change type - [x] `other` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds end-to-end tests and fixtures for groups (CRUD, reorder, file ops, sharing) with supporting test utilities and minor test-id/DO route adjustments. > > - **E2E Tests**: > - Add `tests/groups.spec.ts` covering group create/rename/delete, expand/collapse persistence, reordering via drag, file create/move/drag/pin/unpin/duplicate/delete, move-to-home, and sharing/invitation flows with cross-user propagation. > - **Fixtures/Helpers**: > - New `GroupInviteDialog` fixture; register in `tla-test.ts` and `helpers.ts`. > - Extend `Sidebar` fixture with group operations, file operations within groups, drag-and-drop utilities, and invite-link copy methods; add `createGroupButton` selector. > - `Database` fixture: add `enableGroupsFrontend()` and simplify cleanup to hit `prepare-for-test` without legacy header. > - Remove init-mode code from `HomePage`. > - **App UI**: > - Change sidebar create-group button test id to `tla-create-group` in `TlaSidebar.tsx`. > - **Sync Worker (test utilities)**: > - Simplify `__test__prepareForTest`: always set `groups_backend`, clear all user groups, and recreate home group; update `/app/__test__/user/:userId/prepare-for-test` route accordingly. > - **Cleanup**: > - Remove `run-both-modes.sh` and `init-mode-verification.spec.ts`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 18c142a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 3e7a4a6 commit 42a4388

12 files changed

Lines changed: 1046 additions & 154 deletions

File tree

apps/dotcom/client/e2e/fixtures/Database.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,31 @@ export class Database {
6464
await sql`SELECT * FROM migrate_user_to_groups(${id}, ${inviteSecret})`.execute(db)
6565
}
6666

67+
/**
68+
* Enable groups frontend flag for a user
69+
*/
70+
async enableGroupsFrontend(isOther: boolean = false): Promise<void> {
71+
const id = await this.getUserId(isOther)
72+
if (!id) throw new Error('User not found')
73+
74+
// Get current flags
75+
const result = await sql<{
76+
flags: string | null
77+
}>`SELECT flags FROM public.user WHERE id = ${id}`.execute(db)
78+
79+
const currentFlags = result.rows[0]?.flags || ''
80+
const flagsArray = currentFlags.split(/[,\s]+/).filter(Boolean)
81+
82+
// Add groups_frontend if not present
83+
if (!flagsArray.includes('groups_frontend')) {
84+
flagsArray.push('groups_frontend')
85+
}
86+
87+
// Update with new flags
88+
const newFlags = flagsArray.join(',')
89+
await sql`UPDATE public.user SET flags = ${newFlags} WHERE id = ${id}`.execute(db)
90+
}
91+
6792
private async cleanUpUser(isOther: boolean) {
6893
const fileName = getStorageStateFileName(this.parallelIndex, isOther ? 'suppy' : 'huppy')
6994
if (!fs.existsSync(fileName)) return
@@ -73,9 +98,6 @@ export class Database {
7398
// eslint-disable-next-line no-restricted-globals
7499
await fetch(`http://localhost:3000/api/app/__test__/user/${id}/prepare-for-test`, {
75100
method: 'POST',
76-
headers: {
77-
'x-legacy': process.env.TLDRAW_INIT_MODE === 'new' ? 'false' : 'true',
78-
},
79101
})
80102
} catch (e) {
81103
console.error('Error', e)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { Locator, Page } from '@playwright/test'
2+
import { expect, step } from './tla-test'
3+
4+
export class GroupInviteDialog {
5+
public readonly dialog: Locator
6+
public readonly acceptButton: Locator
7+
public readonly declineButton: Locator
8+
9+
constructor(public readonly page: Page) {
10+
this.dialog = this.page.getByText("You've been invited to group")
11+
this.acceptButton = this.page.getByRole('button', { name: 'Accept and join group' })
12+
this.declineButton = this.page.getByRole('button', { name: 'No thanks' })
13+
}
14+
15+
async isVisible() {
16+
return this.dialog.isVisible()
17+
}
18+
19+
async expectIsVisible() {
20+
await expect(this.dialog).toBeVisible()
21+
}
22+
23+
async expectIsNotVisible() {
24+
await expect(this.dialog).not.toBeVisible()
25+
}
26+
27+
@step
28+
async acceptInvitation() {
29+
await this.acceptButton.click()
30+
}
31+
32+
@step
33+
async declineInvitation() {
34+
await this.declineButton.click()
35+
}
36+
}

apps/dotcom/client/e2e/fixtures/HomePage.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,6 @@ export class HomePage {
1616
this.signInButton = this.page.getByTestId('tla-sign-in-button')
1717
this.tldrawEditor = this.page.getByTestId('tla-editor')
1818
this.tldrawCanvas = this.page.getByTestId('canvas')
19-
20-
// Set localStorage flag based on environment variable
21-
const initMode = process.env.TLDRAW_INIT_MODE || 'legacy'
22-
this.page.addInitScript((mode) => {
23-
if (mode === 'new') {
24-
// eslint-disable-next-line no-restricted-syntax
25-
localStorage.setItem('tldraw_groups_init', 'true')
26-
} else {
27-
// eslint-disable-next-line no-restricted-syntax
28-
localStorage.removeItem('tldraw_groups_init')
29-
}
30-
}, initMode)
3119
}
3220

3321
@step

0 commit comments

Comments
 (0)