Skip to content

Commit

Permalink
Add Playwright to the transition repo, and run a few simple tests on …
Browse files Browse the repository at this point in the history
…github.

Fix: chairemobilite#1065
  • Loading branch information
GabrielBruno24 committed Oct 1, 2024
1 parent 0c7d5f9 commit 3ddbf78
Show file tree
Hide file tree
Showing 14 changed files with 475 additions and 36 deletions.
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,8 @@ MAIL_TRANSPORT_SMTP_AUTH_PWD=password

# From email
MAIL_FROM_ADDRESS=[email protected]

#Parameters used to login to a test account in the playwright tests
PLAYWRIGHT_TEST_USER=testUser
PLAYWRIGHT_TEST_EMAIL=[email protected]
PLAYWRIGHT_TEST_PASSWORD=testPassword
50 changes: 49 additions & 1 deletion .github/workflows/transition.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,32 @@ on:
jobs:
build-and-test:
runs-on: ubuntu-latest
services:
postgres:
image: postgis/postgis
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
POSTGRES_USER: testuser
POSTGRES_PASSWORD: testpassword
POSTGRES_DB: testdb
strategy:
matrix:
node-version: [18.x, 20.x]
env:
PROJECT_CONFIG: ${{ github.workspace }}/examples/config.js
PG_CONNECTION_STRING_PREFIX: postgres://testuser:testpassword@localhost:5432/
PG_DATABASE_PRODUCTION: testdb
PG_DATABASE_DEVELOPMENT: testdb
CI: true ## This is to make sure that the tests run in CI mode
PLAYWRIGHT_TEST_USER: testUser
PLAYWRIGHT_TEST_EMAIL: [email protected]
PLAYWRIGHT_TEST_PASSWORD: testPassword
steps:
- uses: actions/checkout@v4
- name: copy env file
Expand All @@ -33,8 +54,35 @@ jobs:
run: yarn build:prod
- name: Unit Test
run: yarn test
- name: UI Test
# Following configure the automated UI tests
- name: Create DB
run: yarn setup && yarn migrate
env:
NODE_ENV: production
- name: Get Playwright config
run: cp packages/chaire-lib-frontend/playwright-example.config.ts packages/chaire-lib-frontend/playwright.config.ts
- name: Create test user
run: yarn create-user --username $PLAYWRIGHT_TEST_USER --email $PLAYWRIGHT_TEST_EMAIL --password $PLAYWRIGHT_TEST_PASSWORD --admin
- name: Create imports directory
run: mkdir -p examples/runtime/imports
- name: Download OSRM data
run: yarn node --max-old-space-size=4096 packages/chaire-lib-backend/lib/scripts/osrm/downloadOsmNetworkData.task.js --polygon-file examples/polygon_rtl_area.geojson
- name: Prepare OSRM data
run: yarn node --max-old-space-size=4096 packages/chaire-lib-backend/lib/scripts/osrm/prepareOsmNetworkData.task.js --osrm-prefix '' --mode walking,driving
- name: Start application
run: yarn start &
env:
NODE_ENV: production
- name: Run UI tests
run: yarn test:ui
- name: Archive UI Test results
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-results-${{matrix.node-version}} # This is to make sure that the results are stored in a unique name
path: packages/chaire-lib-frontend/test-results
retention-days: 2
# End of automated UI tests

code-lint:
runs-on: ubuntu-latest
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,9 @@ tests/test
profilingData*

#example apps
examples/runtime
examples/runtime

# playwright test output
**/playwright-report/
**/test-results/
**/playwright.config.ts
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,39 @@ For example, to run yarn test in the chaire-lib backend:
You can also run the app this way with:
`docker run -a STDOUT -it -v "${PWD}:/home/project" -w=/home/project/ testtransition yarn start`

### UI testing with Playwright

To execute UI tests with Playwright, you first have to create an account that will be used for logging in to Transition during the tests. This only needs to be done once:
```
yarn create-user --username testUser --email [email protected] --password testPassword --admin
```

Next, configure Playwright by copying the example config file and select the browser to test in:
```
cp packages/chaire-lib-frontend/playwright-example.config.ts packages/chaire-lib-frontend/playwright.config.ts
```

Next, install browser dependencies to correctly execute the tests. If it is not done, an arror message should tell you the command when attempting to run the test. It is possible to install each browser separaly with the following command, for example `firefox`:
```
npx playwright install --with-deps firefox
```

Now that Playwright is configured, you need to start the application as you would to run it normally:
```
yarn build:dev or yarn build:prod
yarn start
```

Then, to run the tests:
```
yarn test:ui
```

You can also use this command to open a graphic interface that allows you to run tests individually and gives more info:
```
yarn test:ui --ui
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"test": "yarn workspaces run test",
"test:unit": "yarn workspaces run test:unit",
"test:sequential": "yarn workspaces run test:sequential",
"test:ui": "yarn workspaces run test:ui",
"test:ui": "yarn workspace chaire-lib-frontend run test:ui",
"lint": "yarn workspaces run lint",
"format": "yarn workspaces run format",
"list-tasks": "yarn workspace transition-backend run list-tasks",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class PrepareOsmNetworkData implements GenericTask {
protected async getModes(defaultModes: unknown, interactive: boolean): Promise<RoutingMode[]> {
const modesArray =
typeof defaultModes === 'string'
? [defaultModes as string]
? defaultModes.split(',')
: Array.isArray(defaultModes)
? (defaultModes as unknown[])
: [];
Expand Down
5 changes: 4 additions & 1 deletion packages/chaire-lib-frontend/.eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
lib/
node_modules/
**/__tests__
jestSetup.ts
jestSetup.ts
ui-tests/
playwright-example.config.ts
playwright.config.ts
3 changes: 2 additions & 1 deletion packages/chaire-lib-frontend/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ module.exports = {
'./jestSetup.ts'
],
testEnvironment: 'jsdom',
snapshotSerializers: ['enzyme-to-json/serializer']
snapshotSerializers: ['enzyme-to-json/serializer'],
modulePathIgnorePatterns: ["spec.ts"],
};
3 changes: 2 additions & 1 deletion packages/chaire-lib-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"test": "cross-env NODE_ENV=test jest --config=jest.config.js",
"test:unit": "cross-env NODE_ENV=test jest --config=jest.config.js",
"test:sequential": "echo 'cross-env NODE_ENV=test jest --config=jest.sequential.config.js --runInBand'",
"test:ui": "echo 'cross-env NODE_ENV=test jest --config=jest.ui.config.js'",
"test:ui": "LOCALE_DIR=$(pwd)/locales npx playwright test",
"lint": "eslint .",
"format": "prettier-eslint $PWD/'src/**/*.{ts,tsx}' --write"
},
Expand Down Expand Up @@ -69,6 +69,7 @@
"typescript": "^4.9.4"
},
"devDependencies": {
"@playwright/test": "^1.47.2",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^10.4.7",
"@types/enzyme": "^3.10.8",
Expand Down
78 changes: 78 additions & 0 deletions packages/chaire-lib-frontend/playwright-example.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import dotenv from 'dotenv';
import path from 'path';
import { defineConfig, devices } from '@playwright/test';

dotenv.config({ path: path.resolve(__dirname, '../../.env') });

export default defineConfig({
testDir: './ui-tests',
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
// Each test is given 15 seconds.
timeout: 15000,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: 'http://localhost:8080',

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
screenshot: 'only-on-failure'
},

/* Configure projects for major browsers */
projects: [
// {
// name: 'chromium',
// use: { ...devices['Desktop Chrome'] },
// },
{
name: 'Google Chrome',
use: { ...devices['Desktop Chrome'], channel: 'chrome' }
}
// {
// name: 'firefox',
// use: { ...devices['Desktop Firefox'] },
// },

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

/* 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' },
// },
],

/* Run your local dev server before starting the tests */
// webServer: {
// command: 'npm run start',
// url: 'http://127.0.0.1:3000',
// reuseExistingServer: !process.env.CI,
// },
});
29 changes: 29 additions & 0 deletions packages/chaire-lib-frontend/ui-tests/loginTestHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2024, Polytechnique Montreal and contributors
*
* This file is licensed under the MIT License.
* License text available at https://opensource.org/licenses/MIT
*/

import * as testHelpers from './testHelpers';

/**
* Test the login page, change to the right language, and login to the test account.
* @param {Object} options - The options for the test.
* @param {string} options.title - The title of the page.
*/
export const startAndLoginAnonymously = ({
context,
title
}: { title: string} & testHelpers.CommonTestParameters) => {
testHelpers.hasTitleTest({ context, title });
testHelpers.hasUrlTest({ context, expectedUrl: '/login' });
testHelpers.isLanguageTest({ context, expectedLanguage: 'fr' });
testHelpers.switchLanguageTest({ context, languageToSwitch: 'en' });
testHelpers.isLanguageTest({ context, expectedLanguage: 'en' });
testHelpers.loginTest({ context });
};

export const logout = ({ context }: testHelpers.CommonTestParameters) => {
testHelpers.logoutTest({ context });
};
39 changes: 39 additions & 0 deletions packages/chaire-lib-frontend/ui-tests/test-left-menu.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2024, Polytechnique Montreal and contributors
*
* This file is licensed under the MIT License.
* License text available at https://opensource.org/licenses/MIT
*/

import { test } from '@playwright/test';
import * as testHelpers from './testHelpers';
import * as loginTestHelpers from './loginTestHelpers';

const context = {
page: null as any,
title: '',
widgetTestCounters: {}
};

// Configure the tests to run in serial mode (one after the other)
test.describe.configure({ mode: 'serial' });

test.beforeAll(async ({ browser }) => {
context.page = await testHelpers.initializeTestPage(browser);
});

loginTestHelpers.startAndLoginAnonymously({ context, title: 'Transition' });

// Click all the sections in the left menu and check that the right panel becomes the correct one.
testHelpers.clickLeftMenuTest({ context, section: 'nodes' });
testHelpers.clickLeftMenuTest({ context, section: 'services' });
testHelpers.clickLeftMenuTest({ context, section: 'scenarios' });
testHelpers.clickLeftMenuTest({ context, section: 'routing' });
testHelpers.clickLeftMenuTest({ context, section: 'accessibilityMap' });
testHelpers.clickLeftMenuTest({ context, section: 'batchCalculation' });
testHelpers.clickLeftMenuTest({ context, section: 'gtfsImport' });
testHelpers.clickLeftMenuTest({ context, section: 'gtfsExport' });
testHelpers.clickLeftMenuTest({ context, section: 'preferences' });
testHelpers.clickLeftMenuTest({ context, section: 'agencies' });

loginTestHelpers.logout({ context });
Loading

0 comments on commit 3ddbf78

Please sign in to comment.