Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test Github CI #2

Merged
merged 8 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Install Playwright Browsers
run: yarn playwright install --with-deps
- name: Run Playwright tests
run: yarn playwright test
run: yarn test:e2e companies
- uses: actions/upload-artifact@v4
if: always()
with:
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ storybook-static
*.tsbuildinfo
.eslintcache
.cache
.nyc_output
.nyc_output
test-results/
7 changes: 6 additions & 1 deletion packages/twenty-e2e-testing/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ [email protected]
# Documentation for REST API: https://twenty.com/developers/rest-api/core#/
# REST_API_BASE_URL=http://localhost:3000/rest/

# Documentation for GraphQL API: https://twenty.com/developers/graphql/core
# GRAPHQL_BASE_URL=http://localhost:3000/graphql

# Without this key, all API tests will fail, to generate this key
# In order to use it, header Authorization: Bearer token must be used
# Log in to Twenty workspace, go to Settings > Developers, generate new key and paste it here
# REST_API_DEV_KEY=fill_with_proper_key
# This key works for REST and GraphQL API
# API_DEV_KEY=fill_with_proper_key
5 changes: 4 additions & 1 deletion packages/twenty-e2e-testing/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ playwright-report/
blob-report/
playwright/.cache/
run_results/
results/
playwright-report/.last-run.json
results/
run_results/.playwright-artifacts-0/
run_results/.playwright-artifacts-1/
4 changes: 2 additions & 2 deletions packages/twenty-e2e-testing/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Twenty e2e Testing

## Install
## Prerequisition

Don't forget to install the browsers before launching the tests :
Installing the browsers:

```
yarn playwright install
Expand Down
35 changes: 18 additions & 17 deletions packages/twenty-e2e-testing/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ config();
*/
export default defineConfig({
testDir: '.',
outputDir: 'run_results/', //
snapshotPathTemplate: '{testDir}/__screenshots__/{testFilePath}/{arg}{ext}',
fullyParallel: true, //
outputDir: 'run_results/', // directory for screenshots and videos
snapshotPathTemplate: '{testDir}/__screenshots__/{testFilePath}/{arg}{ext}', // just in case, do not delete it
fullyParallel: true, // false only for specific tests, overwritten in specific projects or global setups of projects
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
timeout: 5 * 60 * 1000,
timeout: 30 * 1000,
use: {
baseURL: process.env.FRONTEND_BASE_URL ?? 'http://localhost:3001',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
headless: true,
testIdAttribute: 'data-testid',
viewport: { width: 1920, height: 1080 }, // most laptops use this resolution
launchOptions: {
slowMo: 50,
Expand All @@ -39,10 +40,10 @@ export default defineConfig({
use: { ...devices['Desktop Firefox'] },
},

/*{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},*/
//{
// name: 'webkit',
// use: { ...devices['Desktop Safari'] },
//},

/* Test against mobile viewports. */
// {
Expand All @@ -55,19 +56,19 @@ export default defineConfig({
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
//{
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
//},
//{
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
//},
],
/* Run your local dev server before starting the tests */
//webServer: {
// command: 'npx nx start',
// url: 'http://127.0.0.1:3000',
// url: 'http://localhost:3000', // somehow `localhost` is not mapped to 127.0.0.1
// reuseExistingServer: !process.env.CI,
//},
});
9 changes: 6 additions & 3 deletions packages/twenty-e2e-testing/tests/companies.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ test.beforeEach(async ({ page }) => {

test.afterEach(async ({ page, browserName }, workerInfo) => {
await page.screenshot({
path: `./packages/twenty-e2e-testing/results/screenshots/${browserName}/`+workerInfo.project.name+`${date.toISOString()}.png`,
path:
`./packages/twenty-e2e-testing/results/screenshots/${browserName}/` +
workerInfo.project.name +
`${date.toISOString()}.png`,
});
});

Expand All @@ -26,5 +29,5 @@ test.describe('Basic check', () => {
expect(page.url()).toContain('/companies');
await expect(page.locator('table')).toBeVisible();
await expect(page.locator('tbody > tr')).toHaveCount(13);
})
});
});
});
108 changes: 55 additions & 53 deletions packages/twenty-e2e-testing/tests/workspaces.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,69 +3,71 @@ import { sh } from '../drivers/shell_driver';

const date = new Date();

test.beforeEach(async ({ page }) => {
await page.goto('/');
});

test.afterEach(async ({ page, browserName }) => {
await page.screenshot({
path: `./packages/twenty-e2e-testing/results/screenshots/${browserName}/${date.toISOString()}.png`,
});
});

test('Testing logging', async ({ page }) => {
await page.goto('/');
await page.getByRole('button', { name: 'Continue With Email' }).click();
await page.getByPlaceholder('Email').fill('[email protected]');
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByPlaceholder('Password').fill('Applecar2025');
await page.getByRole('button', { name: 'Sign in' }).click();
});

test('Creating new workspace', async ({ page, browserName }) => {
if (browserName == 'firefox') {
await page.goto('/');
await page.getByRole('button', { name: 'Continue With Email' }).click();
await page.getByPlaceholder('Email').fill('[email protected]'); // email must be changed each time test is run
await page.getByPlaceholder('Email').press('Enter'); // otherwise if tests fails after this step, new workspace is created
await page.getByPlaceholder('Password').fill('Applecar2025');
await page.getByPlaceholder('Password').press('Enter');
await page.getByPlaceholder('Apple').fill('Test');
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByPlaceholder('Tim').click();
await page.getByPlaceholder('Tim').fill('Test2');
await page.getByPlaceholder('Cook').click();
await page.getByPlaceholder('Cook').fill('Test2');
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByText('Continue without sync').click();
await page.getByRole('button', { name: 'Finish' }).click();
await expect(page.locator('table')).toBeVisible({ timeout: 1000 });
}
});

test('Syncing all workspaces', async () => {
await sh('npx nx run twenty-server:command workspace:sync-metadata -f');
await sh('npx nx run twenty-server:command workspace:sync-metadata -f');
});

test('Resetting database', async ({ page, browserName }) => {
if (browserName === 'firefox') {
await sh('yarn nx database:reset twenty-server'); // if this command fails for any reason, database must be restarted manually using the same command because database is in unstable state
test.describe('', () => {
test('Testing logging', async ({ page }) => {
await page.goto('/');
await page.getByRole('button', { name: 'Continue With Email' }).click();
await page.getByPlaceholder('Email').fill('[email protected]');
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByPlaceholder('Password').fill('Applecar2025');
await page.getByRole('button', { name: 'Sign in' }).click();
await page.getByRole('link', { name: 'Companies' }).click();
expect(page.url()).toContain('/companies');
await expect(page.locator('table')).toBeVisible();
}
});
await page.getByRole('link', { name: 'Opportunities' }).click();
await expect(page.locator('tbody > tr')).toHaveCount(4);
expect(page.url()).not.toContain('/welcome');
});

test('Seeding database', async ({ page, browserName }) => {
if (browserName === 'firefox') {
await sh('npx nx workspace:seed:demo');
await page.goto('/');
}
});
test('Creating new workspace', async ({ page, browserName }) => {
// this test must use only 1 browser, otherwise it will lead to success and fail (1 workspace is created instead of x workspaces)
if (browserName == 'firefox') {
await page.goto('/');
await page.getByRole('button', { name: 'Continue With Email' }).click();
await page.getByPlaceholder('Email').fill('[email protected]'); // email must be changed each time test is run
await page.getByPlaceholder('Email').press('Enter'); // otherwise if tests fails after this step, new workspace is created
await page.getByPlaceholder('Password').fill('Applecar2025');
await page.getByPlaceholder('Password').press('Enter');
await page.getByPlaceholder('Apple').fill('Test');
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByPlaceholder('Tim').click();
await page.getByPlaceholder('Tim').fill('Test2');
await page.getByPlaceholder('Cook').click();
await page.getByPlaceholder('Cook').fill('Test2');
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByText('Continue without sync').click();
await page.getByRole('button', { name: 'Finish' }).click();
await expect(page.locator('table')).toBeVisible({ timeout: 1000 });
}
});

test('Syncing all workspaces', async () => {
await sh('npx nx run twenty-server:command workspace:sync-metadata -f');
await sh('npx nx run twenty-server:command workspace:sync-metadata -f');
});

test('Resetting database', async ({ page, browserName }) => {
if (browserName === 'firefox') {
await sh('yarn nx database:reset twenty-server'); // if this command fails for any reason, database must be restarted manually using the same command because database is in unstable state
await page.goto('/');
await page.getByRole('button', { name: 'Continue With Email' }).click();
await page.getByPlaceholder('Email').fill('[email protected]');
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByPlaceholder('Password').fill('Applecar2025');
await page.getByRole('button', { name: 'Sign in' }).click();
await page.getByRole('link', { name: 'Companies' }).click();
expect(page.url()).toContain('/companies');
await expect(page.locator('table')).toBeVisible();
}
});

test('Seeding database', async ({ page, browserName }) => {
if (browserName === 'firefox') {
await sh('npx nx workspace:seed:demo');
await page.goto('/');
}
});
});
11 changes: 11 additions & 0 deletions packages/twenty-front/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,16 @@ const config: StorybookConfig = {
name: '@storybook/react-vite',
options: {},
},
viteFinal: async (config) => {
// Merge custom configuration into the default config
const { mergeConfig } = await import('vite');

return mergeConfig(config, {
// Add dependencies to pre-optimization
optimizeDeps: {
exclude: ['@tabler/icons-react'],
},
});
},
};
export default config;
22 changes: 15 additions & 7 deletions packages/twenty-front/src/generated-metadata/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,9 @@ export type FieldConnection = {

/** Type of the field */
export enum FieldMetadataType {
Actor = 'ACTOR',
Address = 'ADDRESS',
Boolean = 'BOOLEAN',
Actor = 'ACTOR',
Currency = 'CURRENCY',
Date = 'DATE',
DateTime = 'DATE_TIME',
Expand Down Expand Up @@ -452,13 +452,13 @@ export type Mutation = {
generateTransientToken: TransientToken;
impersonate: Verify;
renewToken: AuthTokens;
runWorkflowVersion: WorkflowTriggerResult;
sendInviteLink: SendInviteLink;
signUp: LoginToken;
skipSyncEmailOnboardingStep: OnboardingStepSuccess;
syncRemoteTable: RemoteTable;
syncRemoteTableSchemaChanges: RemoteTable;
track: Analytics;
triggerWorkflow: WorkflowTriggerResult;
unsyncRemoteTable: RemoteTable;
updateBillingSubscription: UpdateBillingEntity;
updateOneField: Field;
Expand Down Expand Up @@ -610,6 +610,11 @@ export type MutationRenewTokenArgs = {
};


export type MutationRunWorkflowVersionArgs = {
input: RunWorkflowVersionInput;
};


export type MutationSendInviteLinkArgs = {
emails: Array<Scalars['String']['input']>;
};
Expand Down Expand Up @@ -639,11 +644,6 @@ export type MutationTrackArgs = {
};


export type MutationTriggerWorkflowArgs = {
workflowVersionId: Scalars['String']['input'];
};


export type MutationUnsyncRemoteTableArgs = {
input: RemoteTableInput;
};
Expand Down Expand Up @@ -1001,6 +1001,13 @@ export enum RemoteTableStatus {
Synced = 'SYNCED'
}

export type RunWorkflowVersionInput = {
/** Execution result in JSON format */
payload?: InputMaybe<Scalars['JSON']['input']>;
/** Workflow version ID */
workflowVersionId: Scalars['String']['input'];
};

export type SendInviteLink = {
__typename?: 'SendInviteLink';
/** Boolean that confirms query was dispatched */
Expand Down Expand Up @@ -1400,6 +1407,7 @@ export type WorkspaceFeatureFlagsArgs = {
export enum WorkspaceActivationStatus {
Active = 'ACTIVE',
Inactive = 'INACTIVE',
OngoingCreation = 'ONGOING_CREATION',
PendingCreation = 'PENDING_CREATION'
}

Expand Down
Loading
Loading