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

Merge and check if workflow is inactive #5

Merged
merged 35 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c3d8046
Fix for #6597 Created by field can't have null value
BOHEUS Aug 12, 2024
d3827aa
Playwright initial setup + example tests (WIP)
BOHEUS Aug 13, 2024
cd7a8a3
Merge branch 'twentyhq:main' into playwright_qa_tests
BOHEUS Aug 13, 2024
debcffc
Merge remote-tracking branch 'origin/main'
BOHEUS Aug 14, 2024
9524b9b
Merge branch 'refs/heads/main' into playwright_qa_tests
BOHEUS Aug 14, 2024
53df970
Merge branch 'twentyhq:main' into playwright_qa_tests
BOHEUS Aug 14, 2024
bd3156c
Merge remote-tracking branch 'origin/playwright_qa_tests' into playwr…
BOHEUS Aug 15, 2024
305fc18
Merge branch 'twentyhq:main' into playwright_qa_tests
BOHEUS Aug 15, 2024
8cf8087
Merge remote-tracking branch 'origin/playwright_qa_tests' into playwr…
BOHEUS Aug 15, 2024
bbe0098
Fixed structure of twenty-e2e-testing package, updated configuration …
BOHEUS Aug 15, 2024
af29c59
Merge pull request #1 from BOHEUS/playwright_qa_tests
BOHEUS Aug 16, 2024
b1043e5
Merge branch 'twentyhq:main' into playwright_qa_tests
BOHEUS Aug 16, 2024
1611dc3
Fixes in Github workflow CI
BOHEUS Aug 16, 2024
9662f03
Too big timeout (5m > 30sec)
BOHEUS Aug 16, 2024
9c318b1
Reverting changes introduced in #6621
BOHEUS Aug 16, 2024
012c94a
Revert changes introduced in #6621
BOHEUS Aug 16, 2024
9ac78ae
Changed config and tests
BOHEUS Aug 16, 2024
cbdaa0e
Merge branch 'twentyhq:main' into playwright_qa_tests
BOHEUS Aug 16, 2024
0970c0f
Probably working Github CI
BOHEUS Aug 16, 2024
73cef5d
Merge pull request #2 from BOHEUS/playwright_qa_tests
BOHEUS Aug 16, 2024
d1ee2c2
Merge remote-tracking branch 'origin/main'
BOHEUS Aug 17, 2024
2ede403
Test workflow CI
BOHEUS Aug 17, 2024
1ec1a68
Changed config, fixed test
BOHEUS Aug 17, 2024
e6b0c0c
Merge pull request #3 from BOHEUS/main
BOHEUS Aug 17, 2024
db20a35
Typo in readme
BOHEUS Aug 17, 2024
c8273f3
Fixed baseURL in config
BOHEUS Aug 17, 2024
5f830d4
Merge pull request #4 from BOHEUS/main
BOHEUS Aug 19, 2024
52a3c3d
Deleted duplicate in .gitignore
BOHEUS Aug 21, 2024
c9f8381
Merge branch 'twentyhq:main' into playwright_qa_tests
BOHEUS Aug 21, 2024
ef6620f
Merge remote-tracking branch 'origin/playwright_qa_tests' into playwr…
BOHEUS Aug 21, 2024
da4bd73
Fix logging error in webhook system
charlesBochet Aug 21, 2024
d754415
Merge branch 'twentyhq:main' into playwright_qa_tests
BOHEUS Aug 21, 2024
ce81cef
Merge remote-tracking branch 'origin/playwright_qa_tests' into playwr…
BOHEUS Aug 21, 2024
2d3fd5e
Github CI workflow saved to .yml.bak
BOHEUS Aug 21, 2024
99b5622
Bring back reverted changes from #6621
BOHEUS Aug 21, 2024
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
27 changes: 27 additions & 0 deletions .github/workflows/playwright.yml.bak
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: npm install -g yarn && yarn
- name: Install Playwright Browsers
run: yarn playwright install --with-deps
- name: Run Playwright tests
run: yarn test:e2e companies
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ dist
storybook-static
*.tsbuildinfo
.eslintcache
.cache
.nyc_output
test-results/
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@
"@nx/storybook": "18.3.3",
"@nx/vite": "18.3.3",
"@nx/web": "18.3.3",
"@playwright/test": "^1.46.0",
"@sentry/types": "^7.109.0",
"@storybook/addon-actions": "^7.6.3",
"@storybook/addon-coverage": "^1.0.0",
Expand Down
22 changes: 21 additions & 1 deletion packages/twenty-e2e-testing/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,22 @@
# Note that provide always without trailing forward slash to have expected behaviour
FRONTEND_BASE_URL="http://localhost:3001"
FRONTEND_BASE_URL=http://localhost:3001
CI_DEFAULT_BASE_URL=https://demo.twenty.com
[email protected]
[email protected]
[email protected]
DEFAULT_PASSWORD=Applecar2025
WEBSITE_URL=https://twenty.com

# === DO NOT USE, WORK IN PROGRESS ===
# This URL must have trailing forward slash as all REST API endpoints have object after it
# 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
# Log in to Twenty workspace, go to Settings > Developers, generate new key and paste it here
# In order to use it, header Authorization: Bearer token must be used
# This key works for both REST and GraphQL API
# API_DEV_KEY=fill_with_proper_key
14 changes: 9 additions & 5 deletions packages/twenty-e2e-testing/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
node_modules/
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
test-results/
playwright-report/
blob-report/
playwright/.cache/
run_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
## Prerequisite

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

```
yarn playwright install
Expand Down
33 changes: 33 additions & 0 deletions packages/twenty-e2e-testing/config/customreporter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
Reporter,
FullConfig,
Suite,
TestCase,
TestResult,
FullResult,
} from '@playwright/test/reporter';

class CustomReporter implements Reporter {
constructor(options: { customOption?: string } = {}) {
console.log(
`my-awesome-reporter setup with customOption set to ${options.customOption}`,
);
}

onBegin(config: FullConfig, suite: Suite) {
console.log(`Starting the run with ${suite.allTests().length} tests`);
}

onTestBegin(test: TestCase) {
console.log(`Starting test ${test.title}`);
}

onTestEnd(test: TestCase, result: TestResult) {
console.log(`Finished test ${test.title}: ${result.status}`);
}

onEnd(result: FullResult) {
console.log(`Finished the run: ${result.status}`);
}
}
export default CustomReporter;
13 changes: 13 additions & 0 deletions packages/twenty-e2e-testing/drivers/shell_driver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { exec } from 'child_process';

export async function sh(cmd) {
return new Promise((resolve, reject) => {
exec(cmd, (err, stdout, stderr) => {
if (err) {
reject(err);
} else {
resolve({ stdout, stderr });
}
});
});
}
14 changes: 0 additions & 14 deletions packages/twenty-e2e-testing/e2e/companies.spec.ts

This file was deleted.

69 changes: 49 additions & 20 deletions packages/twenty-e2e-testing/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,72 @@
import { defineConfig, devices } from '@playwright/test';

import { config } from 'dotenv';

config();

/* === Run your local dev server before starting the tests === */

/**
* See https://playwright.dev/docs/test-configuration.
* See https://playwright.dev/docs/trace-viewer to Collect trace when retrying the failed test
*/
export default defineConfig({
testDir: 'e2e',
/* Run tests in files in parallel */
fullyParallel: true,
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
testDir: '.',
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, // undefined = amount of projects
timeout: 30 * 1000, // timeout can be changed
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: process.env.FRONTEND_BASE_URL ?? 'http://localhost:3001',
baseURL: process.env.CI
? process.env.CI_DEFAULT_BASE_URL
: (process.env.FRONTEND_BASE_URL ?? 'http://localhost:3001'),
trace: 'retain-on-failure', // trace takes EVERYTHING from page source, records every single step, should be used only when normal debugging won't work
screenshot: 'on', // either 'on' here or in different method in modules, if 'on' all screenshots are overwritten each time the test is run
headless: true, // instead of changing it to false, run 'yarn test:e2e:debug' or 'yarn test:e2e:ui'
testIdAttribute: 'data-testid', // taken from Twenty source
viewport: { width: 1920, height: 1080 }, // most laptops use this resolution
launchOptions: {
slowMo: 500, // time in milliseconds between each step, better to use it than explicitly define timeout in tests
},
},

/* Configure projects for major browsers */
expect: {
timeout: 5000,
},
reporter: [['html', { open: 'never' }]],
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},

{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},

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

{
name: 'Google Chrome',
use: { ...devices['Desktop Chrome'], channel: 'chrome' },
},
/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },

/* Test against branded browsers. */
//{
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
//},
//{
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
//},
],
});
34 changes: 34 additions & 0 deletions packages/twenty-e2e-testing/tests/companies.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { test, expect } from '@playwright/test';
import { config } from 'dotenv';
import path = require('path');
config({ path: path.resolve(__dirname, '..', '.env') });

const date = new Date();

test.beforeEach(async ({ page }) => {
await page.goto('/');
await page.getByRole('button', { name: 'Continue With Email' }).click();
await page.getByPlaceholder('Email').fill(process.env.DEFAULT_LOGIN);
await page.getByRole('button', { name: 'Continue' }).click();
await page.getByPlaceholder('Password').fill(process.env.DEFAULT_PASSWORD);
await page.getByRole('button', { name: 'Sign in' }).click();
});

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

test.describe('Basic check', () => {
test('Checking if table in Companies is visible', async ({ page }) => {
await expect(page.getByTestId('tooltip').nth(0)).toHaveText('Companies');
await expect(page.getByTestId('tooltip').nth(0)).toBeVisible();
expect(page.url()).toContain('/companies');
await expect(page.locator('table')).toBeVisible();
await expect(page.locator('tbody > tr')).toHaveCount(13); // shouldn't be hardcoded in case of tests on demo
});
});
73 changes: 73 additions & 0 deletions packages/twenty-e2e-testing/tests/workspaces.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { test, expect } from '@playwright/test';
import { sh } from '../drivers/shell_driver';

const date = new Date();

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

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: 'Opportunities' }).click();
await expect(page.locator('tbody > tr')).toHaveCount(4);
expect(page.url()).not.toContain('/welcome');
});

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('/');
}
});
});
3 changes: 3 additions & 0 deletions packages/twenty-front/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,8 @@ export default defineConfig(({ command, mode }) => {
localsConvention: 'camelCaseOnly',
},
},
optimizeDeps: {
exclude: ['@tabler/icons-react'],
},
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export class CallWebhookJobsJob {

if (webhooks.length) {
this.logger.log(
`CallWebhookJobsJob on eventName '${event}' called on webhooks ids [\n"${webhooks
`CallWebhookJobsJob on eventName '${eventName}' called on webhooks ids [\n"${webhooks
.map((webhook) => webhook.id)
.join('",\n"')}"\n]`,
);
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -47255,6 +47255,7 @@ __metadata:
"@nx/vite": "npm:18.3.3"
"@nx/web": "npm:18.3.3"
"@octokit/graphql": "npm:^7.0.2"
"@playwright/test": "npm:^1.46.0"
"@ptc-org/nestjs-query-core": "npm:^4.2.0"
"@ptc-org/nestjs-query-typeorm": "npm:4.2.1-alpha.2"
"@react-email/components": "npm:0.0.12"
Expand Down
Loading