Add E2E tests (#9309)
Try adding E2E tests when labelling the PR or merging on main branch
This commit is contained in:
141
.github/workflows/ci-e2e.yml
vendored
Normal file
141
.github/workflows/ci-e2e.yml
vendored
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
name: CI E2E Tests
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'push' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'run-e2e'))
|
||||||
|
timeout-minutes: 30
|
||||||
|
env:
|
||||||
|
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
|
||||||
|
# https://github.com/actions/runner-images/issues/70#issuecomment-589562148
|
||||||
|
NODE_OPTIONS: "--max-old-space-size=10240"
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: twentycrm/twenty-postgres-spilo
|
||||||
|
env:
|
||||||
|
PGUSER_SUPERUSER: postgres
|
||||||
|
PGPASSWORD_SUPERUSER: postgres
|
||||||
|
ALLOW_NOSSL: "true"
|
||||||
|
SPILO_PROVIDER: "local"
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
options: >-
|
||||||
|
--health-cmd pg_isready
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
|
redis:
|
||||||
|
image: redis
|
||||||
|
ports:
|
||||||
|
- 6379:6379
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
|
||||||
|
- name: Check system resources
|
||||||
|
run: |
|
||||||
|
echo "Available memory:"
|
||||||
|
free -h
|
||||||
|
echo "Available disk space:"
|
||||||
|
df -h
|
||||||
|
echo "CPU info:"
|
||||||
|
lscpu
|
||||||
|
|
||||||
|
- name: Check for changed files
|
||||||
|
id: changed-files
|
||||||
|
uses: tj-actions/changed-files@v11
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
packages/**
|
||||||
|
playwright.config.ts
|
||||||
|
.github/workflows/ci-e2e.yml
|
||||||
|
|
||||||
|
- name: Skip if no relevant changes
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'false'
|
||||||
|
run: echo "No relevant changes detected. Marking as valid."
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
uses: ./.github/workflows/actions/yarn-install
|
||||||
|
|
||||||
|
- name: Build twenty-shared
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: npx nx build twenty-shared
|
||||||
|
|
||||||
|
- name: Setup environment files
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: |
|
||||||
|
cp packages/twenty-e2e-testing/.env.example packages/twenty-e2e-testing/.env
|
||||||
|
cp packages/twenty-front/.env.example packages/twenty-front/.env
|
||||||
|
cp packages/twenty-e2e-testing/.env.example packages/twenty-e2e-testing/.env
|
||||||
|
npx nx reset:env twenty-server
|
||||||
|
|
||||||
|
- name: Build frontend
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: NODE_ENV=production NODE_OPTIONS="--max-old-space-size=10240" npx nx build twenty-front
|
||||||
|
|
||||||
|
- name: Build server
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: NODE_ENV=production npx nx build twenty-server
|
||||||
|
|
||||||
|
- name: Create and setup database
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: |
|
||||||
|
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "default";'
|
||||||
|
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "test";'
|
||||||
|
npx nx run twenty-server:database:reset
|
||||||
|
|
||||||
|
- name: Start server
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: |
|
||||||
|
npx nx start twenty-server &
|
||||||
|
echo "Waiting for server to be ready..."
|
||||||
|
timeout 60 bash -c 'until curl -s http://localhost:3000/health; do sleep 2; done'
|
||||||
|
|
||||||
|
- name: Start frontend
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: |
|
||||||
|
npm_config_yes=true npx serve -s packages/twenty-front/build -l 3001 &
|
||||||
|
echo "Waiting for frontend to be ready..."
|
||||||
|
timeout 60 bash -c 'until curl -s http://localhost:3001; do sleep 2; done'
|
||||||
|
|
||||||
|
- name: Start worker
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: |
|
||||||
|
npx nx run twenty-server:worker:ci &
|
||||||
|
echo "Worker started"
|
||||||
|
|
||||||
|
- name: Install Playwright Browsers
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: npx nx setup twenty-e2e-testing
|
||||||
|
|
||||||
|
- name: Run Playwright tests
|
||||||
|
if: steps.changed-files.outputs.any_changed == 'true'
|
||||||
|
run: npx nx test twenty-e2e-testing
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: playwright-report
|
||||||
|
path: packages/twenty-e2e-testing/run_results/
|
||||||
|
retention-days: 30
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: playwright-report
|
||||||
|
path: packages/twenty-e2e-testing/playwright-report/
|
||||||
|
retention-days: 30
|
||||||
52
.github/workflows/ci-e2e.yml.bak
vendored
52
.github/workflows/ci-e2e.yml.bak
vendored
@ -1,52 +0,0 @@
|
|||||||
name: CI E2E Tests
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- '**'
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
timeout-minutes: 30
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: lts/*
|
|
||||||
|
|
||||||
- name: Check for changed files
|
|
||||||
id: changed-files
|
|
||||||
uses: tj-actions/changed-files@v11
|
|
||||||
with:
|
|
||||||
files: |
|
|
||||||
packages/**
|
|
||||||
playwright.config.ts
|
|
||||||
|
|
||||||
- name: Skip if no relevant changes
|
|
||||||
if: steps.changed-files.outputs.any_changed == 'false'
|
|
||||||
run: echo "No relevant changes detected. Marking as valid."
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
|
||||||
uses: ./.github/workflows/actions/yarn-install
|
|
||||||
- name: Install Playwright Browsers
|
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
|
||||||
run: yarn playwright install --with-deps
|
|
||||||
- name: Run Playwright tests
|
|
||||||
if: steps.changed-files.outputs.any_changed == 'true'
|
|
||||||
run: yarn test:e2e companies
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: playwright-report
|
|
||||||
path: playwright-report/
|
|
||||||
retention-days: 30
|
|
||||||
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@ -14,6 +14,7 @@
|
|||||||
"styled-components.vscode-styled-components",
|
"styled-components.vscode-styled-components",
|
||||||
"unifiedjs.vscode-mdx",
|
"unifiedjs.vscode-mdx",
|
||||||
"xyc.vscode-mdx-preview",
|
"xyc.vscode-mdx-preview",
|
||||||
"yoavbls.pretty-ts-errors"
|
"yoavbls.pretty-ts-errors",
|
||||||
|
"ms-playwright.playwright"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
23
.vscode/launch.json
vendored
23
.vscode/launch.json
vendored
@ -6,12 +6,11 @@
|
|||||||
"name": "twenty-server - start debug",
|
"name": "twenty-server - start debug",
|
||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"runtimeExecutable": "yarn",
|
"runtimeExecutable": "npx",
|
||||||
"runtimeVersion": "18",
|
|
||||||
"runtimeArgs": [
|
"runtimeArgs": [
|
||||||
"nx",
|
"nx",
|
||||||
"run",
|
"run",
|
||||||
"twenty-server:start",
|
"twenty-server:start"
|
||||||
],
|
],
|
||||||
"outputCapture": "std",
|
"outputCapture": "std",
|
||||||
"internalConsoleOptions": "openOnSessionStart",
|
"internalConsoleOptions": "openOnSessionStart",
|
||||||
@ -22,12 +21,11 @@
|
|||||||
"name": "twenty-server - worker debug",
|
"name": "twenty-server - worker debug",
|
||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"runtimeExecutable": "yarn",
|
"runtimeExecutable": "npx",
|
||||||
"runtimeVersion": "18",
|
|
||||||
"runtimeArgs": [
|
"runtimeArgs": [
|
||||||
"nx",
|
"nx",
|
||||||
"run",
|
"run",
|
||||||
"twenty-server:worker",
|
"twenty-server:worker"
|
||||||
],
|
],
|
||||||
"outputCapture": "std",
|
"outputCapture": "std",
|
||||||
"internalConsoleOptions": "openOnSessionStart",
|
"internalConsoleOptions": "openOnSessionStart",
|
||||||
@ -45,12 +43,23 @@
|
|||||||
"run",
|
"run",
|
||||||
"twenty-server:command",
|
"twenty-server:command",
|
||||||
"my-command",
|
"my-command",
|
||||||
"--my-parameter value",
|
"--my-parameter value"
|
||||||
],
|
],
|
||||||
"outputCapture": "std",
|
"outputCapture": "std",
|
||||||
"internalConsoleOptions": "openOnSessionStart",
|
"internalConsoleOptions": "openOnSessionStart",
|
||||||
"console": "internalConsole",
|
"console": "internalConsole",
|
||||||
"cwd": "${workspaceFolder}/packages/twenty-server/"
|
"cwd": "${workspaceFolder}/packages/twenty-server/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Playwright Test current file",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"runtimeExecutable": "npx",
|
||||||
|
"runtimeArgs": ["nx", "test", "twenty-e2e-testing", "${file}"],
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"internalConsoleOptions": "neverOpen",
|
||||||
|
"envFile": "${workspaceFolder}/packages/twenty-e2e-testing/.env"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -48,5 +48,5 @@
|
|||||||
"eslint.debug": true,
|
"eslint.debug": true,
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
".cursorrules": "markdown"
|
".cursorrules": "markdown"
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
4
.vscode/twenty.code-workspace
vendored
4
.vscode/twenty.code-workspace
vendored
@ -44,6 +44,10 @@
|
|||||||
"name": "tools/eslint-rules",
|
"name": "tools/eslint-rules",
|
||||||
"path": "../tools/eslint-rules"
|
"path": "../tools/eslint-rules"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "packages/twenty-e2e-testing",
|
||||||
|
"path": "../packages/twenty-e2e-testing"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"settings": {
|
"settings": {
|
||||||
"editor.formatOnSave": false,
|
"editor.formatOnSave": false,
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
# Note that provide always without trailing forward slash to have expected behaviour
|
# Note that provide always without trailing forward slash to have expected behaviour
|
||||||
FRONTEND_BASE_URL=http://app.localhost:3001
|
FRONTEND_BASE_URL=http://localhost:3001
|
||||||
CI_DEFAULT_BASE_URL=https://demo.twenty.com
|
|
||||||
DEFAULT_LOGIN=tim@apple.dev
|
DEFAULT_LOGIN=tim@apple.dev
|
||||||
NEW_WORKSPACE_LOGIN=test@apple.dev
|
NEW_WORKSPACE_LOGIN=test@apple.dev
|
||||||
DEMO_DEFAULT_LOGIN=noah@demo.dev
|
DEMO_DEFAULT_LOGIN=noah@demo.dev
|
||||||
|
|||||||
@ -2,7 +2,13 @@ import { defineConfig, devices } from '@playwright/test';
|
|||||||
import { config } from 'dotenv';
|
import { config } from 'dotenv';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
config();
|
const envResult = config({
|
||||||
|
path: path.resolve(__dirname, '.env'),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (envResult.error) {
|
||||||
|
throw new Error('Failed to load .env file');
|
||||||
|
}
|
||||||
|
|
||||||
/* === Run your local dev server before starting the tests === */
|
/* === Run your local dev server before starting the tests === */
|
||||||
|
|
||||||
@ -19,9 +25,7 @@ export default defineConfig({
|
|||||||
workers: 1, // 1 worker = 1 test at the time, tests can't be parallelized
|
workers: 1, // 1 worker = 1 test at the time, tests can't be parallelized
|
||||||
timeout: 30 * 1000, // timeout can be changed
|
timeout: 30 * 1000, // timeout can be changed
|
||||||
use: {
|
use: {
|
||||||
baseURL: process.env.CI
|
baseURL: process.env.FRONTEND_BASE_URL || 'http://localhost:3001',
|
||||||
? process.env.CI_DEFAULT_BASE_URL
|
|
||||||
: (process.env.FRONTEND_BASE_URL ?? 'http://app.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
|
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
|
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'
|
headless: true, // instead of changing it to false, run 'yarn test:e2e:debug' or 'yarn test:e2e:ui'
|
||||||
@ -54,7 +58,7 @@ export default defineConfig({
|
|||||||
storageState: path.resolve(__dirname, '.auth', 'user.json'), // takes saved cookies from directory
|
storageState: path.resolve(__dirname, '.auth', 'user.json'), // takes saved cookies from directory
|
||||||
},
|
},
|
||||||
dependencies: ['Login setup'], // forces to run login setup before running tests from this project - CASE SENSITIVE
|
dependencies: ['Login setup'], // forces to run login setup before running tests from this project - CASE SENSITIVE
|
||||||
testMatch: /all\/.+\.spec\.ts/,
|
testMatch: /all\/.+\.e2e-spec\.ts/,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'firefox',
|
name: 'firefox',
|
||||||
@ -63,11 +67,7 @@ export default defineConfig({
|
|||||||
storageState: path.resolve(__dirname, '.auth', 'user.json'),
|
storageState: path.resolve(__dirname, '.auth', 'user.json'),
|
||||||
},
|
},
|
||||||
dependencies: ['Login setup'],
|
dependencies: ['Login setup'],
|
||||||
testMatch: /all\/.+\.spec\.ts/,
|
testMatch: /all\/.+\.e2e-spec\.ts/,
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Authentication',
|
|
||||||
testMatch: /authentication\/.*\.spec\.ts/,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//{
|
//{
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { test, expect } from '../../lib/fixtures/screenshot';
|
import { expect, test } from '../../lib/fixtures/screenshot';
|
||||||
|
|
||||||
test.describe('Basic check', () => {
|
test.describe('Basic check', () => {
|
||||||
test('Checking if table in Companies is visible', async ({ page }) => {
|
test('Checking if table in Companies is visible', async ({ page }) => {
|
||||||
40
packages/twenty-e2e-testing/tests/all/workspaces.e2e-spec.ts
Normal file
40
packages/twenty-e2e-testing/tests/all/workspaces.e2e-spec.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { test } from '@playwright/test';
|
||||||
|
import { sh } from '../../drivers/shell_driver';
|
||||||
|
|
||||||
|
test.describe('', () => {
|
||||||
|
test.use({ storageState: { cookies: [], origins: [] } });
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
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 == 'chromium') {
|
||||||
|
await sh(
|
||||||
|
'npx nx run twenty-server:database:reset --configuration=no-seed',
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.goto('/');
|
||||||
|
await page.getByRole('button', { name: 'Continue With Email' }).click();
|
||||||
|
await page.getByPlaceholder('Email').fill('test@apple.dev'); // 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 });
|
||||||
|
await sh('npx nx run twenty-server:database:reset');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
test('Syncing all workspaces', async () => {
|
||||||
|
await sh('npx nx run twenty-server:command workspace:sync-metadata -f');
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,66 +0,0 @@
|
|||||||
import { test, expect } from '@playwright/test';
|
|
||||||
import { sh } from '../../drivers/shell_driver';
|
|
||||||
|
|
||||||
test.describe('', () => {
|
|
||||||
test('Testing logging', async ({ page }) => {
|
|
||||||
await page.goto('/');
|
|
||||||
await page.getByRole('button', { name: 'Continue With Email' }).click();
|
|
||||||
await page.getByPlaceholder('Email').fill('tim@apple.dev');
|
|
||||||
await page.getByRole('button', { name: 'Continue', exact: true }).click();
|
|
||||||
await page.getByPlaceholder('Password').fill('Applecar2025');
|
|
||||||
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
||||||
await expect(page.getByText('Welcome to Twenty')).not.toBeVisible();
|
|
||||||
expect(page.url()).not.toContain('/welcome');
|
|
||||||
await page.getByRole('link', { name: 'Opportunities' }).click();
|
|
||||||
await expect(page.locator('tbody > tr')).toHaveCount(4);
|
|
||||||
});
|
|
||||||
|
|
||||||
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 == 'chromium') {
|
|
||||||
await page.goto('/');
|
|
||||||
await page.getByRole('button', { name: 'Continue With Email' }).click();
|
|
||||||
await page.getByPlaceholder('Email').fill('test@apple.dev'); // 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 === 'chromium') {
|
|
||||||
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('tim@apple.dev');
|
|
||||||
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 === 'chromium') {
|
|
||||||
await sh('npx nx workspace:seed:demo');
|
|
||||||
await page.goto('/');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
import { test as base, expect } from '../../lib/fixtures/screenshot';
|
|
||||||
import { LoginPage } from '../../lib/pom/loginPage';
|
|
||||||
|
|
||||||
// fixture
|
|
||||||
const test = base.extend<{ loginPage: LoginPage }>({
|
|
||||||
loginPage: async ({ page }, use) => {
|
|
||||||
await use(new LoginPage(page));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Check login with email', async ({ loginPage }) => {
|
|
||||||
await loginPage.typeEmail(process.env.DEFAULT_LOGIN);
|
|
||||||
await loginPage.clickContinueButton();
|
|
||||||
await loginPage.typePassword(process.env.DEFAULT_PASSWORD);
|
|
||||||
await loginPage.clickSignInButton();
|
|
||||||
await expect(loginPage.signInButton).not.toBeVisible();
|
|
||||||
});
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { test, expect } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
test('Check if demo account is working properly @demo-only', async ({
|
test('Check if demo account is working properly @demo-only', async ({
|
||||||
page,
|
page,
|
||||||
@ -1,18 +1,38 @@
|
|||||||
import { test as setup, expect } from '@playwright/test';
|
import { expect, test as setup } from '@playwright/test';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
setup('Login test', async ({ page }) => {
|
setup('Login test', async ({ page }) => {
|
||||||
await page.goto('/');
|
console.log('Starting login test');
|
||||||
await page.getByRole('button', { name: 'Continue With Email' }).click();
|
|
||||||
await page.getByPlaceholder('Email').fill(process.env.DEFAULT_LOGIN);
|
|
||||||
await page.getByRole('button', { name: 'Continue', exact: true }).click();
|
|
||||||
await page.getByPlaceholder('Password').fill(process.env.DEFAULT_PASSWORD);
|
|
||||||
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
||||||
await expect(page.getByText('Welcome to Twenty')).not.toBeVisible();
|
|
||||||
|
|
||||||
// End of authentication steps.
|
await page.goto('/');
|
||||||
|
console.log('Navigated to homepage');
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Continue With Email' }).click();
|
||||||
|
console.log('Clicked email login button');
|
||||||
|
|
||||||
|
console.log('Default login', process.env.DEFAULT_LOGIN);
|
||||||
|
await page.getByPlaceholder('Email').fill(process.env.DEFAULT_LOGIN ?? '');
|
||||||
|
console.log('Filled email field');
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Continue', exact: true }).click();
|
||||||
|
console.log('Clicked continue button');
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByPlaceholder('Password')
|
||||||
|
.fill(process.env.DEFAULT_PASSWORD ?? '');
|
||||||
|
console.log('Filled password field');
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Sign in' }).click();
|
||||||
|
console.log('Clicked sign in button');
|
||||||
|
|
||||||
|
await page.waitForLoadState('networkidle');
|
||||||
|
console.log('Waited for network to be idle');
|
||||||
|
|
||||||
|
await expect(page.getByText('Welcome to Twenty')).not.toBeVisible();
|
||||||
|
console.log('Verified welcome message not visible');
|
||||||
|
|
||||||
await page.context().storageState({
|
await page.context().storageState({
|
||||||
path: path.resolve(__dirname, '..', '.auth', 'user.json'),
|
path: path.resolve(__dirname, '..', '.auth', 'user.json'),
|
||||||
});
|
});
|
||||||
|
console.log('Saved auth state');
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true NODE_OPTIONS=--max-old-space-size=3000 npx vite build && sh ./scripts/inject-runtime-env.sh",
|
"build": "VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true NODE_OPTIONS=--max-old-space-size=4000 npx vite build && sh ./scripts/inject-runtime-env.sh",
|
||||||
"build:sourcemaps": "VITE_BUILD_SOURCEMAP=true VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true NODE_OPTIONS=--max-old-space-size=6000 npx vite build && sh ./scripts/inject-runtime-env.sh",
|
"build:sourcemaps": "VITE_BUILD_SOURCEMAP=true VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true NODE_OPTIONS=--max-old-space-size=6000 npx vite build && sh ./scripts/inject-runtime-env.sh",
|
||||||
"start:prod": "NODE_ENV=production npx vite --host",
|
"start:prod": "NODE_ENV=production npx vite --host",
|
||||||
"tsup": "npx tsup"
|
"tsup": "npx tsup"
|
||||||
|
|||||||
Reference in New Issue
Block a user