/ tests / ecosystems.spec.ts
ecosystems.spec.ts
 1  import { test as base, expect } from '@playwright/test';
 2  import createEcosystemPayload from './create-ecosystem-payload.json' with { type: 'json' };
 3  import { ConnectedSession, TEST_ADDRESSES } from './fixtures/ConnectedSession';
 4  import workerUniqueString from './utils/worker-unique-string';
 5  
 6  const test = base.extend<{
 7    connectedSession: ConnectedSession;
 8  }>({
 9    connectedSession: async ({ page }, use) => {
10      const connectedSession = new ConnectedSession(page, TEST_ADDRESSES[0]);
11      await connectedSession.goto();
12      await connectedSession.connect();
13  
14      await use(connectedSession);
15    },
16  });
17  
18  test('ecosystems donation flow', async ({ connectedSession, request }, testInfo) => {
19    const { page } = connectedSession;
20    test.setTimeout(240_000);
21  
22    const ecosystemName = workerUniqueString(testInfo, 'Test Ecosystem');
23  
24    // create the ecosystem
25    const ecosystemCreatedResponse = await request.post('http://localhost:5173/api/ecosystems', {
26      data: {
27        ...createEcosystemPayload,
28        name: ecosystemName,
29      },
30    });
31    expect(ecosystemCreatedResponse.ok()).toBeTruthy();
32  
33    // wait for ecosystem to be in the correct state for deployment
34    await page.waitForTimeout(5_000);
35  
36    // deploy the ecosystem
37    const { id } = await ecosystemCreatedResponse.json();
38    const ecosystemDeployedResponse = await request.post(
39      `http://localhost:5173/api/ecosystems/${id}/deploy`,
40    );
41    expect(ecosystemDeployedResponse.ok()).toBeTruthy();
42  
43    await page.getByTestId('sidenav-item-Ecosystems').click();
44    await expect(page.getByRole('heading', { name: 'Ecosystems' })).toBeVisible();
45  
46    // wait for the api to return an ecosystem that we can support
47    // by checking for the appearance of funds donated
48  
49    let fundsDisplaying = false;
50  
51    while (!fundsDisplaying) {
52      await page.reload();
53      await page.getByRole('button', { name: 'Connect', exact: true }).click();
54      await page.getByTestId('sidenav-item-Ecosystems').click();
55      // NOTE: strategically placed timeout!
56      await page.waitForTimeout(1_000);
57      const fundsCount = await page.getByTestId(`ecosystem-card-${id}`).getByText('Funds').count();
58  
59      fundsDisplaying = fundsCount > 0;
60    }
61  
62    // navigate to the created ecosystem
63    await page.locator(`text=${ecosystemName}`).nth(0).click();
64  
65    // verify that the distribution details are correct
66    await page.waitForTimeout(1_000);
67    expect(await page.getByText('50%').count()).toBe(2);
68  
69    // perform a one-time donation
70    await page.getByRole('button', { name: 'Support' }).nth(0).click();
71    await page.getByRole('button', { name: 'One-time donation' }).first().click();
72    await page.getByText('Test Token').click();
73  
74    // Wait for token balance to load completely before interacting with amount input
75    // The token balance fetch is async, and while loading, the input value gets reset to '0'
76    // This can cause a race condition where Playwright's fill() conflicts with the reactive reset
77    await expect(page.getByText('TEST', { exact: true }).last()).toBeVisible({ timeout: 10000 });
78  
79    // Additional safety: wait a brief moment for all reactive statements to settle
80    await page.waitForTimeout(500);
81  
82    await page.getByRole('spinbutton', { name: 'TEST Amount' }).click();
83    await page.getByRole('spinbutton', { name: 'TEST Amount' }).fill('10');
84    await page.getByRole('button', { name: 'Confirm in your wallet' }).click();
85    await page.getByRole('button', { name: 'Continue' }).click();
86    await page.getByRole('button', { name: 'Got it' }).click();
87  
88    // verify that support shows the donation
89    await expect(page.getByText('10 TEST').nth(0)).toBeVisible();
90  
91    // verify that the ecosystem support has propagated to the relevant projects.
92    const page1Promise = page.waitForEvent('popup');
93    // skip root node
94    await page.getByRole('link', { name: createEcosystemPayload.graph.nodes[1].projectName }).click();
95    const page1 = await page1Promise;
96    await expect(page1.locator(`text=${ecosystemName}`).nth(0)).toBeVisible();
97    await expect(page1.getByText('50%').first()).toBeVisible();
98  });